Listview优化从数据库获取的数据

时间:2015-05-19 03:38:10

标签: android listview android-listview android-viewholder

我对android非常陌生并寻求有关从数据库获取的数据的 listview优化的帮助。 “我想检查框,然后按下获取按钮显示它们敬酒。“

使用 SimpleCursorAdapter

package com.example.adapterx;


import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.widget.SimpleCursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;


public class MainActivity extends Activity {

DBAdapter myDb;            

@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    openDB();
    display();
    insertdata();

}


private void insertdata() {

String pap = "1";
String pap1 = "2";
String pap2 = "3";
String pap3 = "4";
String pap4= "5";
String pap5 = "6";
String pap6 = "7";
String pap7 = "8";
String pap8 = "9";
String pap9 = "10";
String pap10 = "11";
String pap11 = "12";
String pap12 = "13";
String pap13= "14";
String pap14 = "15";
String pap15 = "16";
String pap16 = "17";
String pap17 = "18";
String pap18 = "19";
String pap19 = "20";
String pap20 = "21";
String pap21 = "22";
String pap22 = "23";


myDb.insertRow(pap);
myDb.insertRow(pap1);
myDb.insertRow(pap2);
myDb.insertRow(pap3);
myDb.insertRow(pap4);
myDb.insertRow(pap5);
myDb.insertRow(pap6);
myDb.insertRow(pap7);
myDb.insertRow(pap8);
myDb.insertRow(pap9);
myDb.insertRow(pap10);
myDb.insertRow(pap11);
myDb.insertRow(pap12);
myDb.insertRow(pap13);
myDb.insertRow(pap14);
myDb.insertRow(pap15);
myDb.insertRow(pap16);
myDb.insertRow(pap17);
myDb.insertRow(pap18);
myDb.insertRow(pap19);
myDb.insertRow(pap20);
myDb.insertRow(pap21);
myDb.insertRow(pap22);
Toast.makeText(this, "inserted successfully.",    Toast.LENGTH_LONG).show();

}


 @Override
protected void onDestroy() {
super.onDestroy();  
closeDB();
}
 private void openDB() {
myDb = new DBAdapter(this);
myDb.open();
}
private void closeDB() {
myDb.close();
}


private void display() {

    final Cursor cursor = myDb.getAllRows();
    String[] fromFieldNames = new String[]{DBAdapter.KEY_NAME};
    int[] toViewIDs = new int[]{R.id.textsv};
    SimpleCursorAdapter myCursorAdapter;
    myCursorAdapter= new     SimpleCursorAdapter(getBaseContext(),R.layout.item_layoutt,cursor , fromFieldNames , toViewIDs ,0);
    final ListView myList = (ListView) findViewById(R.id.listView1);
    myList.setAdapter(myCursorAdapter);


}

activity_main.xml中

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.adapterx.MainActivity" >

<ListView
    android:id="@+id/listView1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_below="@+id/textView1" >

</ListView>

<Button
    android:id="@+id/get"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/listView1"
    android:layout_alignParentTop="true"
    android:layout_alignRight="@+id/listView1"
    android:text="Get" />

</RelativeLayout>

item_layoutt.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >

<CheckBox
    android:id="@+id/textcb"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

<TextView
    android:id="@+id/textsv"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="10dp"
    android:text="TextView" />

</LinearLayout>

enter image description here

它完美地显示了列表,但当我点击任何复选框时,选中的项目会重复并在向上和向下滚动时发生变化。

我不知道如何使用 ViewHolder 来解决这个问题。我读了一篇文章http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/,但我没有优化listview。

如何使用 MyCustomAdapter 类修改MainActivity类来解决此问题。请帮我完成整个代码。

private class MyCustomAdapter extends dataAdapter {

 private LayoutInflater mInflater;
 private Cursor cur;

 public MyCustomAdapter(Context context, Cursor c) {
 super(context,c);   
 this.mInflater = LayoutInflater.from(context);
 this.cur = c;
 }


 @Override
 public View getView(int position, View convertView, ViewGroup parent) {

 ViewHolder holder = null;

 if (convertView == null) {
 convertView = this.mInflater.inflate(R.layout.chamber_item, null);
            viewHolder = new ViewHolder();
            viewHolder.text = (TextView)convertView.findViewById(R.id.textsv);
            viewHolder.checkbox =  (CheckBox)convertView.findViewById(R.id.textcb);

            convertView.setTag(viewHolder);
 } 
 else {
 holder = (ViewHolder) convertView.getTag();
 }
 this.cur.moveToPosition(position);

             viewHolder.text.setText(this.cur.getString(this.cur.getColumnIndex("texts")));          
          viewHolder.checkbox.setText(this.cur.getString(this.cur.getColumnIndex("istrue")));
       return convertView;
   }
   static class ViewHolder
    {
        TextView text;
        CheckBox checkbox;

    }

 }

2 个答案:

答案 0 :(得分:0)

尝试以下适配器并查看它是否有帮助。

 private static class MyCustomAdapter extends dataAdapter  {

     private LayoutInflater mInflater;
     private Cursor cur;
     private HashMap<Integer, Boolean> tracker = new HashMap<Integer, Boolean>();

     public MyCustomAdapter(Context context, Cursor c) {
      super(context,c);   
      this.mInflater = LayoutInflater.from(context);
      this.cur = c;
      for(int i=0;i<c.getCount();i++){
         tracker.put(i, false);
      }
     }


     @Override
     public View getView(final int position, View convertView, ViewGroup parent) {

     final ViewHolder holder = null;

     if (convertView == null) {
     convertView = this.mInflater.inflate(R.layout.chamber_item, null);
                holder = new ViewHolder();
                holder .text = (TextView)convertView.findViewById(R.id.textsv);
                holder .checkbox =  (CheckBox)convertView.findViewById(R.id.textcb); 
                convertView.setTag(holder );
     } 
     else {
     holder = (ViewHolder) convertView.getTag();
     }
     this.cur.moveToPosition(position);
     holder.checkbox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            tracker.put(position, isChecked);
        }
    });
     holder.text.setText(this.cur.getString(this.cur.getColumnIndex("texts")));          
     holder.checkbox.setText(this.cur.getString(this.cur.getColumnIndex("istrue")));
     holder.checkbox.setChecked(tracker.get(position));

           return convertView;
       }
       static class ViewHolder
        {
            TextView text;
            CheckBox checkbox;
        }


     }

答案 1 :(得分:0)

添加private ArrayList<Integer> selectedPosision = new ArrayList<Integer>以保留所选的复选框位置,以便在滚动列表视图时帮助您,因为getview(...)方法也会调用此时间。在你的getView(...)参数中设置final int position这可以防止在你只点击一个itme时随机选择你的列表项。并添加clickListener以保持复选框(已选中或未选中)的状态.. viewHolder.checkbox.setChecked(selectedPosition.indexOf(position)>-1);此行确保选中此复选框或不在...每次列表滚动时... 。

   private class MyCustomAdapter extends dataAdapter {

     private LayoutInflater mInflater;
     private Cursor cur;
     private ArrayList<Integer> selectedPosision = new ArrayList<Integer> ();

     public MyCustomAdapter(Context context, Cursor c) {
     super(context,c);   
     this.mInflater = LayoutInflater.from(context);
     this.cur = c;
     }


     @Override
     public View getView(final int position, View convertView, ViewGroup parent) {

     ViewHolder holder = null;

     if (convertView == null) {
     convertView = this.mInflater.inflate(R.layout.chamber_item, null);
                viewHolder = new ViewHolder();
                viewHolder.text = (TextView)convertView.findViewById(R.id.textsv);
                viewHolder.checkbox =  (CheckBox)convertView.findViewById(R.id.textcb);

                convertView.setTag(viewHolder);
     } 
     else {
     holder = (ViewHolder) convertView.getTag();
     }
     this.cur.moveToPosition(position);

                 viewHolder.text.setText(this.cur.getString(this.cur.getColumnIndex("texts")));          
              viewHolder.checkbox.setText(this.cur.getString(this.cur.getColumnIndex("istrue")));

viewHolder.checkbox.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub                  
                    if (selectedPosition.indexOf(position) > -1) {
                      selectedPosition.remove(selectedPosition.indexOf(position));
                    } else {
                       selectedPosition.add(position);
                    }

                }
            });
            viewHolder.checkbox.setChecked(selectedPosition.indexOf(position)>-1);
           return convertView;
       }
       static class ViewHolder
        {
            TextView text;
            CheckBox checkbox;

        }

     }