android ListView重繪的三種方法
阿新 • • 發佈:2019-01-30
1.直接在繼承介面卡類的子類中的getView方法裡執行notifyDataSetChanged方法:
舉個栗子,在listView的item的xml中新增一個button,點選該button,那麼就會刪除該資料。
list_item.xml如下所示:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="3" android:orientation="vertical"> <TextView android:id="@+id/DataID" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="TextView"android:textSize="18sp" /> <TextView android:id="@+id/DataInfo" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="TextView" android:textSize="18sp" /> </LinearLayout> <Space android:layout_width="0dp" android:layout_height="wrap_content"android:layout_weight="2" /> <Button android:id="@+id/DeleteData" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="2" android:text="@string/delete_data" /> </LinearLayout>
自定義的介面卡類MyBaseAdapter如下所示:
package com.example.dell.listviewsqlite; import android.content.Context; import android.content.DialogInterface; import android.database.sqlite.SQLiteDatabase; import android.support.v7.app.AlertDialog; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.TextView; import java.util.ArrayList; /** * Created by dell on 2017/12/1. */ public class MyBaseAdapter extends BaseAdapter { private ArrayList<String> dataID; private ArrayList<String> dataInfo; private LayoutInflater mInflater; private Context mainContext; private SQLiteOp sqLiteOp; public MyBaseAdapter(Context context,SQLiteOp sqLiteOp, ArrayList<String> dataID, ArrayList<String> dataInfo){ this.dataID=dataID; this.dataInfo=dataInfo; this.mInflater = LayoutInflater.from(context); this.mainContext=context; this.sqLiteOp=sqLiteOp; } @Override public int getCount() { return this.dataID.size(); } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { holder=new ViewHolder(); convertView = mInflater.inflate(R.layout.list_item, parent,false); holder.id = (TextView)convertView.findViewById(R.id.DataID); holder.data = (TextView)convertView.findViewById(R.id.DataInfo); holder.deleteBtn=(Button)convertView.findViewById(R.id.DeleteData); convertView.setTag(holder); }else { holder = (ViewHolder)convertView.getTag(); } holder.id.setText(this.dataID.get(position)); holder.data.setText(this.dataInfo.get(position)); holder.deleteBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { showInfo(position); } }); return convertView; } // listview中點選按鍵彈出對話方塊 private void showInfo(final int position) { new AlertDialog.Builder(this.mainContext).setTitle("我的提示").setMessage("確定要刪除嗎?") .setPositiveButton("確定",new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dataID.remove(position); dataInfo.remove(position); deleteDataInDB(position); // 通過程式我們知道刪除了,但是怎麼重新整理ListView呢? // 只需要重新設定一下adapter notifyDataSetChanged(); }} ) .setNegativeButton("取消",null) .show(); } private void deleteDataInDB(int position){ SQLiteDatabase db=this.sqLiteOp.getWritableDatabase(); String whereClause = "id=?"; String[] whereArgs = {this.dataID.get(position)}; db.delete("testDB",whereClause,whereArgs); db.close(); } class ViewHolder { TextView id; TextView data; Button deleteBtn; } }
上述程式碼中有個showInfo方法,在list_item中的button的onclick函式中被呼叫,裡面主要是一個對話方塊,查問是否刪除該item,是則刪除需要展示的資料,然後進行list_view的重繪,即進行:
dataID.remove(position); dataInfo.remove(position);notifyDataSetChanged();dataID和dataInfo都是自定義的資料,型別為ArrayList,分別對應list_item中的兩個TextView。
2.利用訊息回傳機制,在父窗體的onActivityResult對介面卡listView和物件進行重新賦值。
舉個栗子,我們現在把listView中要展示的資料存在SQLite中,我們可以在父窗體點選新增資料按鈕,跳轉到子窗體。在子窗體新增完資料後,跳轉回父窗體,父窗體要重新整理listView。
1.為了進行資料回傳,首先在父窗體進行如下操作建立子窗體:
this.addDataBtn=(Button)findViewById(R.id.AddData); addDataBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent=new Intent(MainActivity.this,InputData.class); startActivityForResult(intent,1); } });上述程式碼點選ID為AddData的button即跳轉到子窗體。
2.在子窗體更新完listView中要展示的資料後(假設資料存在SQLite中,這樣父窗體和子窗體都可以隨意處理listView中要展示的資料),要返回父窗體:
addDataBtn=(Button)findViewById(R.id.SureAddData); addDataBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String inputString=InputData.this.inputText.getText().toString(); if(checkInput(inputString)){ Intent intent=new Intent(); intent.putExtra("InputData",inputString); setResult(1,intent); finish(); } } });在點選ID為SureAddData的按鈕後,程式返回父窗體。
3.過載父窗體的onActivityResult方法,對介面卡和listView物件重新賦值:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(requestCode==1&&resultCode==1){ String inputData=data.getStringExtra("InputData"); addIntoSQLite(inputData); resetListView(); // Toast.makeText(MainActivity.this,inputData,Toast.LENGTH_LONG).show(); } } private void resetListView(){ this.resetData(); myBaseAdapter=new MyBaseAdapter(this,this.sqLiteOp,this.dataID,this.dataInfo); showListView.setAdapter(myBaseAdapter); } private void resetData(){ this.dataID.clear(); this.dataInfo.clear(); this.getDataFromDB(); } private void getDataFromDB() { SQLiteDatabase db = this.sqLiteOp.getReadableDatabase(); String[] columns = {"id", "data"}; Cursor cursor = db.query("testDB", columns, null, null, null, null, null); //判斷遊標是否為空 if (cursor.moveToFirst()) { do{ int id = cursor.getInt(0); this.dataID.add(String.valueOf(id)); String dataInfo = cursor.getString(1); this.dataInfo.add(dataInfo); }while (cursor.moveToNext()); } cursor.close(); db.close(); }
3.過載父窗體的onResume方法,在裡面對對介面卡和listView物件重新賦值:
栗子同上,我們現在listView中要展示的資料存在SQLite中,我們可以在父窗體點選新增資料按鈕,跳轉到子窗體。在子窗體新增完資料後,跳轉回父窗體,父窗體要重新整理listView。
1.按普通方法建立子窗體:
this.addDataBtn=(Button)findViewById(R.id.AddData); addDataBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent=new Intent(MainActivity.this,InputData.class); startActivity(intent); } });
2.子窗體更新完資料後,放回父窗體:
addDataBtn=(Button)findViewById(R.id.SureAddData); addDataBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent=new Intent();finish(); } });
3.過載父窗體的onResume方法:
@Override protected void onResume() { super.onResume();
resetListView();
}private void resetListView(){ this.resetData(); myBaseAdapter=new MyBaseAdapter(this,this.sqLiteOp,this.dataID,this.dataInfo); showListView.setAdapter(myBaseAdapter); } private void resetData(){ this.dataID.clear(); this.dataInfo.clear(); this.getDataFromDB(); } private void getDataFromDB() { SQLiteDatabase db = this.sqLiteOp.getReadableDatabase(); String[] columns = {"id", "data"}; Cursor cursor = db.query("testDB", columns, null, null, null, null, null); //判斷遊標是否為空 if (cursor.moveToFirst()) { do{ int id = cursor.getInt(0); this.dataID.add(String.valueOf(id)); String dataInfo = cursor.getString(1); this.dataInfo.add(dataInfo); }while (cursor.moveToNext()); } cursor.close(); db.close(); }