[Android RecyclerView+SearchView+RESTAPI(runOnUIThread関連)


Androidアプリを初めて作ったときに出会ったホットスポットです.
今見たら当たり前だけど覚えたいだけ!
状況:「追加場所」画面で検索語を入力し、エンターテイメントを行うとLISA群集を見せたいのですが、エラーもなく、LISA群集もありません.
問題は次のとおりです.
getNaverSearch():Naver領域検索REST APIを使用して検索結果をグループ化し、各位置の情報をSearchPlaceItem Arraylistに含める
  • onCreateは、SearchViewのOnQueryTextListener(テキスト入力完了後(=Enter)操作のListener)にgetNaverSearchというメソッドを実行するためのThreadを作成しましたが、NotifyDataSetChardedはどこに置いても実行を続行できません.Threadでグループ外ビューのItemを変更した場合、runOnUIThreadを呼び出し、notifyDataSetChardedを呼び出す必要があります.それでも成功しなかった...解決策は2番
  • です
  • Google化も出ていないので、SearchPlaceItemArrayListだけに追加するのではなく、Adapter(SearchPlaceAdapter)でaddItemsというメソッドを作成し、GetNaverSearchの次の部分(RunOnUIThread呼び出しの前の部分)でaddItemsにaddItemsを提供しました.結果は良好に動作しました.
  • それ以外に、1回のクリックで起動できず、2回目のクリックで正常なグループ外ビューが現れ、getNaverSearchを呼び出すスレッド内でrunOnUIThreadを一緒に呼び出すことに成功する現象もあります.PlaceActivityのonCreateで...
    @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_place);
    
            fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
    
            s_recycler = (RecyclerView) findViewById(R.id.rv_search_place);
            s_recycler.setHasFixedSize(true);
            s_recycler.setLayoutManager(new LinearLayoutManager(this));
            adapter = new SearchPlaceAdapter(this, list);
            s_recycler.setAdapter(adapter);
    
            mSearchView = findViewById(R.id.searchView); // SearchView
            mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
                @Override
                public boolean onQueryTextSubmit(String s) {
                    // 입력받은 문자열 처리
                    final String query = s;
                    //Toast.makeText(LocalSearchActivity.this, "[검색버튼클릭] 검색어 = "+s, Toast.LENGTH_LONG).show();
    
                    // Thread로 웹서버에 접속
                    new Thread() {
                        public void run() {
                            getNaverSearch(query);
                            adapter.addItems(list);
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    adapter.notifyDataSetChanged();
                                }
                            });
                        }
                    }.start();
    
                    return true;
                }
    
                @Override
                public boolean onQueryTextChange(String s) {
                    // 입력란의 문자열이 바뀔 때 처리
                    //Toast.makeText(LocalSearchActivity.this, "입력하고있는 단어 = "+s, Toast.LENGTH_LONG).show();
    
                    return false;
                }
            });
        }
    SearchPlaceAdapterで...下部にaddItemsを追加
    public class SearchPlaceAdapter extends RecyclerView.Adapter<SearchPlaceAdapter.ViewHolder>{
        private ArrayList<SearchedPlaceItem> s_placeList = null ;
        Context context;
    
        // item view를 저장하는 ViewHolder Class
        public class ViewHolder extends RecyclerView.ViewHolder{
            TextView title;
            TextView distance;
            TextView category;
            Button selectBtn;
    
            TextView address;
    
            public ViewHolder(@NonNull View itemView) {
                super(itemView);
                // View 객체에 대한 참조
                title = itemView.findViewById(R.id.s_title);
                distance = itemView.findViewById(R.id.s_distance);
                category = itemView.findViewById(R.id.s_category);
                selectBtn = itemView.findViewById(R.id.selectBtn);
            }
        }
    
        public SearchPlaceAdapter(Context context, ArrayList<SearchedPlaceItem> list){
            this.s_placeList = list;
            this.context = context;
        }
    
        @NonNull
        @Override
        public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            //Context context = parent.getContext() ;
            LayoutInflater inflater = LayoutInflater.from(parent.getContext()) ;
    
            View view = inflater.inflate(R.layout.search_place_item, parent, false) ;
            SearchPlaceAdapter.ViewHolder vh = new SearchPlaceAdapter.ViewHolder(view) ;
    
            return vh ;
        }
    
        @Override
        public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
            final SearchedPlaceItem s_placeItem = s_placeList.get(position);
    
            holder.title.setText(s_placeItem.getTitle());
            holder.distance.setText(s_placeItem.getDistance());
            holder.category.setText(s_placeItem.getCatecory());
            //holder.address.setText(s_placeItem.getAddress());    //장소선택 액티비티에서 InfoActivity로 갈때 필요한지 모르겠..
    
            holder.selectBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
    
                    Toast.makeText(view.getContext(), "장소"+ position +" 선택 완료", Toast.LENGTH_SHORT).show();
                    //Intent intent = new Intent(context, InfoActivity.class);
                    //intent.putExtra("title", s_placeItem.getTitle());
                    //context.startActivity(null);
    
                }
            });
        }
    
        @Override
        public int getItemCount() {
            return (null != s_placeList ? s_placeList.size():0);
        }
    
        public void addItems(ArrayList<SearchedPlaceItem> items){
            this.s_placeList = items;
        }
    }