Newer
Older
NemophilaClient / app / src / main / java / com / example / nemophila / MapsActivity.java
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; }

    }

}