iT邦幫忙

2023 iThome 鐵人賽

DAY 20
0

前言

這次的實作會使用到EditText輸入要搜尋的資料,然後按下按鍵後會叫出Dialog將相關的資料顯示出來,關於這部分的模糊搜尋會用到陣列跟EditText結合,先將假資料加進陣列,然後使用EditText的addTextChangedListener將相關的資料重新填入到陣列中,最後在讓Dialog裡面的RecyclerView顯示更新過後的陣列的資料,以此來完成模糊搜尋的功能。

執行成果

布局設定

首先附上這次的GitHub

  • activity_main

https://ithelp.ithome.com.tw/upload/images/20230930/20161500cvLRH6VneV.png
這次的實作主要是使用EditText輸入關鍵字,按下搜尋後就去比對輸入的資料,先將原本的陣列清空,再將過濾過的資料都加入到清空的陣列,最後再把更新過資料的陣列丟給Dialog裡面的RecyclerView,用這種方式就可以做出模擬搜尋的效果。

  • dialog

https://ithelp.ithome.com.tw/upload/images/20230930/20161500G5gurWcHyg.png
對話框的部分

  • recycleritem

https://ithelp.ithome.com.tw/upload/images/20230930/201615004sPf59BpOG.png
RecyclerView的Item

剩下的還有邊框的設定、假資料以及新增的顏色,這部分就請去GitHub翻了。

MainActivity

這次的實作還做了點擊RecyclerView的選項後,就將資料填到EditText,這部分我是在MainActivity中建立了一個方法,然後在RecyclerView的Adapter中的點擊事件監聽器呼叫了這個方法,在點擊當下就把點擊到的選項傳回到MainActivity的方法,透過點擊後才呼叫方法的方式,將資料填入到EditText。

private ArrayList<String> fuzzyMatching;

先建立一個ArrayList用來存取假資料

    fuzzyMatching = new ArrayList<>();
    Collections.addAll(fuzzyMatching,getResources().getStringArray(R.array.fruits_name));

將ArrayList初始化後,我使用到Collections.addAll這個方法,這個可以幫忙將一個陣列的元素加入到另外一個陣列,使用方法是先將要放入資料的陣列填入,接著將資料來源填入就可以囉~

    dialog = new Dialog(this);
    dialog.setContentView(R.layout.dialog);
    recyclerView = dialog.findViewById(R.id.recyclerView);

再來這個部分比較特別的是,RecyclerView因為是放在Dialog裡面,所以要在Dialog初始化並指定完頁面後,才可以綁定物件id

    setEditText();

    search.setOnClickListener(view -> setDialog(fuzzyMatching));

再來這個部分我將一些較複雜的部份外包出去,搜尋按鈕的部分在建立Dialog的同時將資料傳入

  • setDialog

    private void setDialog(ArrayList<String> filterData) {
        dialogListAdapter = new DialogListAdapter(filterData,this);
        recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
        recyclerView.setAdapter(dialogListAdapter);
        dialog.show();
    }

因為我將RecyclerView放在Dialog裡面,所以設定RecyclerView的相關設定也都是寫在這裡,這裡我傳入Adapter中的除了資料以外,還傳入了MainActivity,這部分就留到Adapter在詳細說明。

  • setEditText

private void setEditText() {
        enter_name.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                fuzzyMatching.clear();
            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}

            @Override
            public void afterTextChanged(Editable editable) {
                String filterText = editable.toString().toLower
                fuzzyMatching.clear();
                for (String data : getResources().getStringArray(R.array.fruits_name)){
                    if (data.toLowerCase().contains(filterText)){
                        fuzzyMatching.add(data);
                    }
                }
            }
        });
    }

這次實作的模糊搜尋使用到EditText的addTextChangedListener,主要會使用到afterTextChanged輸入完後會EditText做的事

String filterText = editable.toString().toLower
fuzzyMatching.clear();

這個部分我將輸入的資料用一個String存取,並且讓它全部都變成小寫
接著把原本的資料都清除

        for (String data : getResources().getStringArray(R.array.fruits_name)){
            if (data.toLowerCase().contains(filterText)){
                fuzzyMatching.add(data);
            }
        }

最後將塞選過的資料填入陣列,用一個String去走訪原本的資料,接著一樣把原本的資料用成小寫,在去對比輸入的資料有沒有包含在原本的資料內,有就將他加進陣列中。

  • 將RecyclerView點擊的資料填到EditText

    public void receiveData(String data){
        enter_name.setText(data);
        dialog.dismiss();
    }

我先建立了一個public的方法,預計讓Adapter調用

DialogListAdapter

    private ArrayList<String> mArrayList;
    private MainActivity mainActivity;//為了要調用MainActivity的方法
    public DialogListAdapter(ArrayList<String> arrayList,MainActivity activity){
        this.mArrayList = arrayList;
        this.mainActivity = activity;
        //接收資料以及獲取Activity
    }

這次跟之前教學一樣,在建構元的部分我設定要傳資料進來,並且還設定要傳送MainActivity的Activity,這樣我就可以使用MainActivity的方法

    public class ViewHolder extends RecyclerView.ViewHolder {
        private TextView fruits_name;
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            fruits_name = itemView.findViewById(R.id.fruits_name);
        }
    }
    @NonNull
    @Override
    public DialogListAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycleritem,parent,false);
        return new ViewHolder(view);
    }

接著綁定id跟item的部分還是一樣

    @Override
    public void onBindViewHolder(@NonNull DialogListAdapter.ViewHolder holder, int position) {
        holder.fruits_name.setText(mArrayList.get(position));

        holder.itemView.setOnClickListener(view -> {
            mainActivity.receiveData(mArrayList.get(position));
            Log.d("test", "按下RecyclerItem");
        });
    }

再來設定要執行的動作這邊,除了最基本的設定每一個選項的TextView以外,還有設定選項的點擊事件,當點擊後就呼叫MainActivity的reciveData並把點擊到的資料傳進去

    public void receiveData(String data){
        enter_name.setText(data);
        dialog.dismiss();
    }

接著這裡就會被呼叫,然後就會執行裡面的動作,將資料填入EditText再將Dialog關閉。

以上就是這次的文章,因為只有加入RecyclerView的Dialog感覺太無聊,所以這次又介紹了模糊搜尋跟怎麼將資料傳回Activity,下一篇會簡單介紹怎麼使用Toast跟Log。


上一篇
【DAY 19】 RecyclerView結合Intent
下一篇
【DAY 21】 簡單介紹Toast、Log
系列文
Android Studio開發過程和介紹30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言