編輯:關於Android編程
MVP模式 ListView中嵌入checkBox的使用
本文寫的是一個小demo,如何在ListView中嵌入checkBox配合使用,本篇文章與前面的嵌入Button類似,同樣的采用MVP模式的寫代碼,本次案例中會有幾個小細節,我將會在案例中介紹。
程序基本框架如下:
View層:
MainActivity.java
public class MainActivity extends AppCompatActivity implements ViewInter<MyBean>{ //ListView的控件名 private ListView mList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mList = (ListView)findViewById(R.id.mList); //開始向presenter層請求數據 new Presenter(this).load(); } /** * presenter層將數據通過接口回調把數據傳遞給這個方法 * 通過這個方法可以將數據項傳遞給適配器 */ @Override public void showData(List<MyBean> myBeen) { MyAdapter adapter = new MyAdapter(myBeen); mList.setAdapter(adapter); } }
ViewInter.java
/** * view層所有的界面更新,請求數據等功能都寫在此接口,方便擴展 */ public interface ViewInter<T> { void showData(List<T> t); }
Presenter層:
Presenter.java
public class Presenter { //view層的對象,主要調用其子類自身的方法,然後回傳數據 ViewInter<MyBean> vi; //model層的對象,主要調用其子類功能,實現數據獲取 ModelInter mi; /** * 只需要傳遞view層的引用即可,model層的數據其由自身去處理 */ public Presenter(ViewInter<MyBean> vi){ this.vi = vi; mi = new ModelImp(); } /** * 該方法的主要功能就是負責數據的傳遞和通知處理數據 */ public void load(){ //調用mi.getData方法,可以獲取需要的數據,然後回調給view層 mi.getData(new ModelInter.DealData() { @Override public void setData() { List<MyBean> data = new ArrayList<>(); for(int i = 0; i < 10; i++){ MyBean bean = new MyBean(); //這裡是隨機生成實體類中的數據,也就是設置復選框是否默認為選上狀態 bean.setChecked(Math.random() > 0.5 ? true : false); data.add(bean); } //回調傳遞數據 vi.showData(data); } }); } }
Model層:
ModelInter.java
/** * 所有模型層的功能都可以寫在此接口中,此接口方便擴展新功能 */ public interface ModelInter { void getData(DealData dealData); public interface DealData{ void setData(); } }
ModelImp.java
public class ModelImp implements ModelInter{ /** * 實現數據的處理,方法中的參數是一個接口類型,所有傳遞過來的值都必須實現其定義的方法 */ @Override public void getData(DealData dealData) { dealData.setData(); } }
Adapter.java
public class MyAdapter extends BaseAdapter implements CompoundButton.OnCheckedChangeListener { //定義一個類似於map集合的對象,其效率會比map更高,用來保存復選框當前被用戶點擊後的狀態 private SparseArray<Boolean> array; private Context context; private List<MyBean> data; public MyAdapter(List<MyBean> data) { this.data = data; array = new SparseArray(); } @Override public int getCount() { return data == null ? 0 : data.size(); } @Override public Object getItem(int i) { return data.get(i); } @Override public long getItemId(int i) { return i; } @Override public View getView(int position, View convertView, ViewGroup parent) { MyBean bean = data.get(position); if (context == null) context = parent.getContext(); ViewHolder holder = null; if (convertView == null) { convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, null); holder = new ViewHolder(); holder.mTv = (TextView) convertView.findViewById(R.id.mTv); holder.mCheck = (CheckBox) convertView.findViewById(R.id.mCheck); convertView.setTag(holder); } holder = (ViewHolder) convertView.getTag(); holder.mTv.setText("復選框" + position); //設置復選框的監聽事件 holder.mCheck.setOnCheckedChangeListener(this); holder.mCheck.setText("編程" + position); //將對應位置設置到tag中 holder.mCheck.setTag(R.id.check, position); //首先判斷數據項中的數據是否為true,如果為true則設置其默認值 // if(data.get(position).isChecked()) //已注釋 // holder.mCheck.setChecked(data.get(position).isChecked());//已注釋 //將用戶選擇的狀態保存到對應的item復選框上 // holder.mCheck.setChecked(array.get(position, false));//已注釋 return convertView; } @Override public void onCheckedChanged(CompoundButton compoundButton, boolean b) { //每次觸發事件的時候,都拿到對應item位置的值 // int i = (int) compoundButton.getTag(R.id.check);//已注釋 //然後將狀態保存到集合中 // array.put(i, b);//已注釋 //並且修改數據項的值。 // data.get(i).setChecked(b);//已注釋 } static class ViewHolder { TextView mTv; CheckBox mCheck; } }
MyBean.java
//數據項對象 public class MyBean { boolean isChecked; public boolean isChecked() { return isChecked; } public void setChecked(boolean checked) { isChecked = checked; } }
基本的代碼都已經實現,我們來看看如果缺少MyAdapter.java中的getView方法中的注釋的代碼所產生的運行效果圖:
從這個運行效果來看,我們明顯可以看出一下小BUG,一開始的時候復選框都是沒有選中,當我們自己選中第一個復選框的時候,我們往下拖動的時候,你會看到,復選框7明顯也跟著被選上了,當我們在此選中復選框2的時候,復選框8也隨之選中了,那麼這是什麼原因呢,這是因為在ListView的一個復用控件機制導致的,關於此問題,本博客中前面的基礎已經講解原理,本案例中就不做詳細講解。
最後我們看下取消那些注釋的代碼後的運行結果圖:
從這個運行結果可以看到,由於默認數據選擇的是1 、 2 、5 當我們取消1、2選擇0時,下面的復用組件就不會想上面的運行結果一樣被復用了,這樣才是正常的選擇了,想選擇就選擇,想取消就取消。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持本站。
這是在網上找的,不過忘了在哪裡找的,經過很多比較測試,發現這個方法不會 oom,目前來看 我一直沒有遇過,今天才找到這個以前建立的工程,記錄下來:先給大家展示下效果圖:p
版本:1.0 日期:2014.6.11 2014.6.12版權:© 2014 kince 轉載注明出處 ImageView是開發中經常使用到的一個控件,也可以
Android總體有五大布局: 線性布局(LiearLayout): 屏幕垂直或水平方向布局。 幀布局(FrameLayout):控件從屏幕左上角開始布局。 相對布
本文實例為大家分享了Android實現一個仿支付寶支付密碼的輸入框,主要實現如下:PasswordView.javapackage com.jackie.alipay.p