package com.example.nemophila; import androidx.annotation.NonNull; import androidx.appcompat.app.ActionBarDrawerToggle; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.SearchView; import androidx.appcompat.widget.Toolbar; import androidx.drawerlayout.widget.DrawerLayout; import androidx.fragment.app.DialogFragment; import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProvider; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; import android.os.Bundle; import android.os.Handler; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import com.example.nemophila.entities.AccountNameJson; import com.example.nemophila.entities.Shop; import com.example.nemophila.viewmodels.FriendViewModel; import com.example.nemophila.viewmodels.ShopsViewModel; import com.google.android.gms.maps.model.Marker; import com.google.android.material.navigation.NavigationView; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class MapsActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { private final ExecutorService executor = Executors.newSingleThreadExecutor(); private final Handler handler = new Handler(); Nemophila nemophila; ShopsViewModel shopsViewModel; FriendViewModel friendViewModel; DialogFragment filterDialog; MapsFragment mapsFragment; // フィルターのリスト用 ArrayList<FilterDataModel> listData; ListView list; boolean isGenre; String genreData[]; ArrayList<String> UsersData; String iconUrlString; String iconUrlStringFriend; @Override protected void onCreate(Bundle savedInstanceState) { shopsViewModel = new ViewModelProvider(this).get(ShopsViewModel.class); friendViewModel = new ViewModelProvider(this).get(FriendViewModel.class); super.onCreate(savedInstanceState); setContentView(R.layout.activity_maps); nemophila = (Nemophila) this.getApplication(); Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); getSupportActionBar().setDisplayShowTitleEnabled(false); // DrawerToggle DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( this, drawer, toolbar, R.string.drawer_open, R.string.drawer_close); drawer.addDrawerListener(toggle); toggle.syncState(); // NavigationView Listener NavigationView navigationView = (NavigationView) findViewById(R.id.navView); navigationView.setNavigationItemSelectedListener(this); // 検索バーの処理 SearchView searchView = findViewById(R.id.tool_search); searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { //文字列を入力後にEnterなど、検索確定したとき @Override public boolean onQueryTextSubmit(String query) { if(query == null) { Toast.makeText(MapsActivity.this, String.format("住所や施設名を入力してください"), Toast.LENGTH_SHORT) .show(); } else { System.out.println("------検索内容---------"); System.out.println(query); System.out.println("----------------------"); //mapsFragment側で地名検索,見つかった場合はその地点に画面移動 mapsFragment.SeachLocation(query); } return false; } //検索文字に変化があったとき @Override public boolean onQueryTextChange(String newText) { System.out.println("------文字列変化検出------"); System.out.println(newText); System.out.println("----------------------"); return false; } }); // サイドメニューのボタン Button genreButton = findViewById(R.id.filter_genre_button); Button friendButton = findViewById(R.id.filter_friends_button); // 押したボタンを灰色にし、listを作成 genreButton.setOnClickListener(view -> { genreButton.setBackgroundColor(Color.parseColor("#afafb0")); friendButton.setBackgroundColor(Color.WHITE); prepareGenreList(null); }); friendButton.setOnClickListener(view -> { friendButton.setBackgroundColor(Color.parseColor("#afafb0")); genreButton.setBackgroundColor(Color.WHITE); prepareFriendList(null); }); // サイドメニューのフィルターのリストの準備 genreData = new String[]{"和食", "洋食", "中華", "イタリアン", "フレンチ", "その他海外料理", "カフェ", "バー", "居酒屋", "焼肉", "鍋", "カレー", "丼", "ラーメン", "うどん", "そば", "その他"}; UsersData = new ArrayList<>(); //自分自身をfilterにかけられるように追加しておく UsersData.add(nemophila.getUid()); //フレンド一覧を取得 friendViewModel.getFriends(nemophila.getUid()); friendViewModel.getFriendsLiveData().observe(this, new Observer<Collection<AccountNameJson>>() { @Override public void onChanged(Collection<AccountNameJson> friends) { for (AccountNameJson friend : friends) { UsersData.add(friend.getUid()); } } }); listData = new ArrayList<>(); list = findViewById(R.id.drawer_list); prepareGenreList(null); // フィルターを有効にする list.setTextFilterEnabled(true); //サイドメニューの検索バー SearchView listSearch = findViewById(R.id.drawer_search); listSearch.setOnQueryTextListener( new SearchView.OnQueryTextListener() { // 入力テキストに変更があったとき @Override public boolean onQueryTextChange(String s) { if(isGenre){ if(s.equals("")){ prepareGenreList(null); } else { prepareGenreList(s); } } else { if(s.equals("")){ prepareFriendList(null); } else { prepareFriendList(s); } } return false; } // 検索ボタンを押したとき @Override public boolean onQueryTextSubmit(String s) { return false; } } ); } //右上のメニューを用意、マイページ画面への遷移 @Override public boolean onCreateOptionsMenu(@NonNull Menu menu) { getMenuInflater().inflate(R.menu.tool_menu, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { Intent intent = new Intent(MapsActivity.this, MyPageActivity.class); startActivity(intent); return super.onOptionsItemSelected(item); } //ジャンルfilter設定画面になったとき public void prepareGenreList(String s){ //sは検索欄に入力された文字列 // 現在表示されているリストがジャンルのリストかどうかを設定 isGenre = true; // 一度リストのデータを取り除いてから追加する listData.clear(); for(int i = 0; i < genreData.length; i++){ if(s == null) { FilterDataModel fd = new FilterDataModel(); fd.setText(genreData[i]); listData.add(fd); } else { if(genreData[i].contains(s)){ FilterDataModel fd = new FilterDataModel(); fd.setText(genreData[i]); listData.add(fd); } } } // ListViewにデータをセットする list.setAdapter(new MyAdapter( this, R.layout.filter_layout, listData )); } //ユーザーfilter設定画面になったとき public void prepareFriendList(String s){ //sは検索欄に入力された文字列 // 現在表示されているリストがジャンルのリストかどうかを設定 isGenre = false; //アイコン仮セット //iconUrlString = "http://nitta-lab-www.is.konan-u.ac.jp/nemophila-data/test01.jpg"; //本来はuidからurl作る //自分のアイコンを取得 String uid = nemophila.getUid(); iconUrlString = "http://nitta-lab-www.is.konan-u.ac.jp/nemophila-data/icon"+uid+".jpg";; // 一度リストのデータを取り除いてから追加する listData.clear(); FilterDataModel fd = new FilterDataModel(); //まず自分をトップに表示する fd.setText(nemophila.getUid()); fd.setNameText(nemophila.getName()); executor.execute(() -> { try{ URL iconUrl = new URL(iconUrlString); HttpURLConnection con = (HttpURLConnection) iconUrl.openConnection(); con.connect(); InputStream is = con.getInputStream(); Bitmap bitmap = BitmapFactory.decodeStream(is); handler.post(() -> { fd.setImage(bitmap); MyAdapter adapter = (MyAdapter) list.getAdapter(); adapter.notifyDataSetChanged(); }); is.close(); con.disconnect(); }catch (Exception e){ e.printStackTrace(); } }); listData.add(fd); //自分の下にフレンド executor.execute(() -> { HashMap<AccountNameJson, Bitmap> bitmaps = new HashMap<>(); HashMap<AccountNameJson, FilterDataModel> fds = new HashMap<>(); for (AccountNameJson friend : nemophila.getFriends()) { if(s == null) { FilterDataModel fd2 = new FilterDataModel(); String fUid = friend.getUid(); fd2.setText(fUid); fd2.setNameText(friend.getName()); //HashMapに追加しておく fds.put(friend,fd2); //そのユーザーのアイコン画像URLを指定 iconUrlStringFriend = ("http://nitta-lab-www.is.konan-u.ac.jp/nemophila-data/icon"+fUid+".jpg"); try{ URL iconUrl = new URL(iconUrlStringFriend); HttpURLConnection con = (HttpURLConnection) iconUrl.openConnection(); con.connect(); InputStream is = con.getInputStream(); Bitmap bitmap = BitmapFactory.decodeStream(is); bitmaps.put(friend, bitmap); is.close(); con.disconnect(); }catch (Exception e){ e.printStackTrace(); } listData.add(fd2); } else { //検索にヒットしたフレンドのみのリストにする if(friend.getName().contains(s)){ FilterDataModel fd2 = new FilterDataModel(); String fUid = friend.getUid(); fd2.setText(fUid); fd2.setNameText(friend.getName()); //HashMapに追加しておく fds.put(friend,fd2); //そのユーザーのアイコン画像URLを指定 iconUrlStringFriend = ("http://nitta-lab-www.is.konan-u.ac.jp/nemophila-data/icon"+fUid+".jpg"); try{ URL iconUrl = new URL(iconUrlStringFriend); HttpURLConnection con = (HttpURLConnection) iconUrl.openConnection(); con.connect(); InputStream is = con.getInputStream(); Bitmap bitmap = BitmapFactory.decodeStream(is); bitmaps.put(friend, bitmap); is.close(); con.disconnect(); }catch (Exception e){ e.printStackTrace(); } listData.add(fd2); } } } for (AccountNameJson friend : nemophila.getFriends()) { if(s == null) { handler.post(() -> { fds.get(friend).setImage(bitmaps.get(friend)); MyAdapter adapter = (MyAdapter) list.getAdapter(); adapter.notifyDataSetChanged(); }); } else { if(friend.getName().contains(s)) { handler.post(() -> { fds.get(friend).setImage(bitmaps.get(friend)); MyAdapter adapter = (MyAdapter) list.getAdapter(); adapter.notifyDataSetChanged(); }); } } } }); // ListViewにデータをセットする list.setAdapter(new MyAdapter( this, R.layout.filter_layout, listData )); } @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { return false; } public void setMapsFragment(MapsFragment mapsFragment) { this.mapsFragment = mapsFragment; } // 内部クラス private class MyAdapter extends ArrayAdapter<FilterDataModel> { private LayoutInflater layoutInflater; public MyAdapter(Context context, int resourceId, List<FilterDataModel> objects){ super(context, resourceId, objects); layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } // 画面外に行ったときにチェックがはずれないようにする @Override public View getView(int position, View convertView, ViewGroup parent) { CheckBox checkBox; if (isGenre) { FilterDataModel item = (FilterDataModel) getItem(position); if (convertView == null) { convertView = layoutInflater.inflate(R.layout.filter_item, null); } TextView textView = convertView.findViewById(R.id.filter_text); textView.setText(item.text); checkBox = convertView.findViewById(R.id.filter_checkbox); checkBox.setOnCheckedChangeListener(null); //チェック済みの項目をチェックにしておく checkBox.setChecked(nemophila.getSelectGenres().contains(item.getText())); } else { FilterDataModel item = (FilterDataModel) getItem(position); if (convertView == null) { convertView = layoutInflater.inflate(R.layout.filter_friend_item, null); } ImageView imageView = convertView.findViewById(R.id.filter_friend_ic); TextView textView = convertView.findViewById(R.id.filter_text); TextView nameTextView = convertView.findViewById(R.id.filter_name); imageView.setImageBitmap(item.image); textView.setText(item.text); nameTextView.setText(item.nameText); checkBox = convertView.findViewById(R.id.filter_checkbox); checkBox.setOnCheckedChangeListener(null); //チェック済みの項目をチェックにしておく checkBox.setChecked(nemophila.getSelectFriends().contains(item.getText())); } // チェックボックスを押したときの処理 //bがtrueでチェック状態を指す checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean b) { if(b) { if(isGenre) { nemophila.setSelectGenres(listData.get(position).getText()); } else { nemophila.setSelectFriends(listData.get(position).getText()); } } else { if(isGenre) { nemophila.removeSelectGenres(listData.get(position).getText()); } else { nemophila.removeSelectFriends(listData.get(position).getText()); } } FilterDataModel data = getItem(position); data.isChecked = b; //shopsViewModelのPreShoplistは、現在取得した全てのshopを持っている Collection<Shop> shops = shopsViewModel.getPreShoplist(); if ( shops != null ) { System.out.println(shops); for (Shop shop : shops) { Marker setMarker = shopsViewModel.getMarker(shop); ArrayList<String> userIdSet = (ArrayList<String>)shop.getUserIdSet().clone(); UsersData.add(nemophila.getUid()); userIdSet.retainAll(UsersData); //自分とそのフレンド以外の投稿は確認しない if( userIdSet.size() > 0) { //場合分け //フィルターを一切かけていないとき if(nemophila.getSelectGenres().isEmpty() && nemophila.getSelectFriends().isEmpty()){ setMarker.setVisible(true); } //ジャンルのみフィルターをかけているとき else if(nemophila.getSelectFriends().isEmpty()) { for(String genre : nemophila.getSelectGenres()) { if(shop.getGenreSet().contains(genre)) { setMarker.setVisible(true); break; } else { setMarker.setVisible(false); } } } //フレンドのみフィルターをかけているとき else if(nemophila.getSelectGenres().isEmpty()) { for(String friendId : nemophila.getSelectFriends()) { if(shop.getUserIdSet().contains(friendId)) { setMarker.setVisible(true); break; } else { setMarker.setVisible(false); } } } //どちらもフィルターをかけているとき else { for(String genre : nemophila.getSelectGenres()) { for(String friendId : nemophila.getSelectFriends()) { if (shop.getGenreSet().contains(genre) && shop.getUserIdSet().contains(friendId)) { setMarker.setVisible(true); break; } else { setMarker.setVisible(false); } } } } } else { setMarker.setVisible(false); } } } } }); return convertView; } } private static class FilterDataModel{ private String text; private String nameText; private Bitmap image; private boolean isChecked; public String getText() { return text; } public void setText(String text) { this.text = text; } public void setNameText(String text) { this.nameText = text; } public void setImage(Bitmap ic) { this.image = ic; } } }