RecyclerView/ListView中包含多個EditText

接近尾聲之時,小夥伴又給我提了一個需求,讓我做一個類似於Excel的表格,大致就是如下圖這樣。

我們可以看到這裏面不僅有多個editText,還有圖片,一次要給x個數據項。

在此我建議使用RecyclerView,使用ListView會很有很多問題,處理起來很麻煩,比如我1,2行輸入的內容,可能會被複用到其他行去。而在RecyclerView裏面很輕鬆就能解決這個問題。

思路我們先整理一下。所有的數據都在Adapter裏面,我們要把內容從Adapter傳到Activity,又或者說,Activity能夠獲取到此時此刻Adapter裏面的數據。怎麼傳?

我們先列舉一個實體類。

public class DeviceAllInfoBean implements Serializable {
     String name;//名字
     String age;//年齡
     String height;//身高
     String imgStream;//圖片

    public DeviceAllInfoBean(String imgStream,String name,String age,String height) {
        this.imgStream=imgStream;
        this.name=name;
        this.age=age;
        this.height=height;
    }

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getImgStream() {
        return deviceTime;
    }

    public void setImgStream(String imgStream) {
        this.imgStream= imgStream;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age= age;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public String getHeight() {
        return height;
    }

    public void setHeight(String height) {
        this.height= height;
    }
}

然後我們在Adapter裏面通過實體,來設置實體內容,然後用一個public方法,通過Gson把實體轉化成Json數據,返回給Activity。

放碼過來:

1、在Adapter的構造器內,進行一個for循環,循環次數x.這裏我就循環6次,也就是初始化的時候,有6行,行內數據爲空。

public MyAdapter(Context context,List<DeviceAllInfoBean> deviceAllInfoBeanList) {
        entities = new ArrayList<DeviceAllInfoBean>();
        for (int i = 0; i < 6; i++) {
                DeviceAllInfoBean entities = new DeviceAllInfoBean(“”,null,null,null);
                this.entities.add(entities);
        }
    }

2、在onBindViewHolder中遍歷值,獲取每一個的值

注:entities是一個List數組:List<DeviceAllInfoBean> entities;可以看做一個暫時存儲器,來存放後面editText的實體內容。

final DeviceAllInfoBean deviceAllInfoBean = this.entities.get(position);
        String str_name = deviceAllInfoBean.name;

接下來在上面代碼的下面,設置值到實體類中,存入tag中。(setTag有暫時存儲數據的功效,不知道這麼說準確不,但是這裏確實是有暫時存儲的作用)

((ViewHold) holder).et_name.setText(TextUtils.isEmpty(str_name) ? "" : str_name);
deviceAllInfoBean.setName((TextUtils.isEmpty(str_name) ? "" : str_name));

 ((ViewHold) holder).et_name.setTag(deviceAllInfoBean);

爲了防止,你輸入了1,2的數據,下面的都被填滿成1,2的數據。我們就加一句這個,防止數據複用。

注:這個方法是RecyclerView的方法,ListView是沒有這個方法的。

holder.setIsRecyclable(false);//不使用複用 防止數據多時 複用時  多個item中的EditText填寫的數據一樣

接下來,設置監聽:EditText我一共用了兩個監聽。

①addTextChangedListener  文本監聽

這裏面做的操作是:拿到setTag中的實體類,且把這個實體賦值給一個新的實體對象,將觸發TextChange的editText現在的值獲取到,賦值給實體的對應的屬性。最後將以前的position的值用List裏面的set方法進行值的替換。

注:list.set(position,bean);是替換某一個position對應的值。

((ViewHold) holder).et_name.addTextChangedListener(new TextWatcher() {//監聽EditText的text變化
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after){

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                DeviceAllInfoBean entities1 = (DeviceAllInfoBean) ((ViewHold) holder).et_name.getTag();
                entities1.setName(((ViewHold) holder).et_name.getText().toString());
                entities.set(position, entities1);
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

②OnFocusChangeListener  焦點監聽

在焦點獲取到的狀態下,獲取存存入tag中的值,且將值設置到控件上。

在失去焦點的狀態下,獲取editText輸入的值,且設置到實體中。

View.OnFocusChangeListener listener = new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View view, boolean b) {
             if(!isFromImg){
                  if (!b) {
                    if (view == ((ViewHold) holder).et_name) {
                        DeviceAllInfoBean entities = (DeviceAllInfoBean) ((ViewHold) holder).et_name.getTag();
                        entities.setName(((ViewHold) holder).et_name.getText().toString());
                    } 
                } else{
                    if (view == ((ViewHold) holder).et_name) {
                        DeviceAllInfoBean entities1 = (DeviceAllInfoBean) ((ViewHold) holder).et_name.getTag();
                        String et_name1 = entities1.deviceName;
                        ((ViewHold) holder).et_name.setText(TextUtils.isEmpty(et_name1) ? "" : et_name1);
                    }
                }
}
               
            }
        };
/**
*isFromImg是一個boolean值,是一個標識,用於判斷是否是選擇圖片之後的焦點監聽
*(我在選擇頭像圖片之後,不監聽焦點事件。)不用的可以不要這個isFromImg條件。
*/

別忘了給editText設置焦點監聽:

((ViewHold) holder).et_name.setOnFocusChangeListener(listener);

然後寫一個方法,可以讓Activity調用這個方法來獲取到Adapter中所有EditText值的方法。

public String getDataToActivity() {
        return new Gson().toJson(entities);
    }

然後再Activity中去調用這個方法,獲取到這6個Item中所有的Json數據。

最後,選擇圖片,直接在item的ImageView上添加一個點擊事件,跳轉到圖片選擇界面。可能你有點迷茫,在Adapter中的onClick中去調用StartActivitieForResult,在哪裏去接收?網上很多都有講,在Adapter中發出,那麼在其所在的Activity中用onActivity去接收數據。

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK&&null!=data) {
            final ArrayList<String> pathList = data.getStringArrayListExtra(PhotoPickerActivity.EXTRA_RESULT_SELECTION);
            final boolean original =
                    data.getBooleanExtra(PhotoPickerActivity.EXTRA_RESULT_ORIGINAL, false);
            myAdapter.setNewData(position,pathList);
        }
    }
/**
*在圖片選擇界面選擇/拍照之後,setResult,調用該Activity的onActivity。
*pathList是選擇的圖片集合。多選就可以用List裝,單選也可以用List(如果不考慮List所佔用資源的話)
*這裏的setNewData(int,)是Adapter中的一個方法,把img本地的地址傳遞到這裏,然後傳遞到Adapter中,進行顯示。
*/

最後我們來看Adapter中的setNewData()這個方法。

/**
*設置圖片到item中。(理解意思就行了。這些操作都是自由發揮的。)
*/
public void setNewData(int itemPosition,List<String> data) {
        this.itemPosition=itemPosition;
        this.listOfImg.clear();
        if (data != null) {
            this.listOfImg.addAll(data);
        }
        imgPath=listOfImg.get(0);

        entities.get(itemPosition).setImgStream(imgPath);
        isFromImg=true;
        notifyDataSetChanged();
    }

到這裏就差不多完成了一個RecyclerView內item有多個EditText,且包含圖片選擇並顯示在item上的操作。

圖片選擇有很多封裝好的第三方,很好用。大家隨意在網上找就好。

有問題可以多多交流,我也是才弄得這個,暫時還沒發現問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章