1. 程式人生 > >android ListView重繪的三種方法

android ListView重繪的三種方法

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();
}