接近尾聲之時,小夥伴又給我提了一個需求,讓我做一個類似於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上的操作。
圖片選擇有很多封裝好的第三方,很好用。大家隨意在網上找就好。
有問題可以多多交流,我也是才弄得這個,暫時還沒發現問題。