滚动时Android自定义列表视图加载速度慢

时间:2016-05-30 10:10:27

标签: android sqlite listview

在我的自定义列表视图中,当我尝试向下滚动以查看新的列表项(底部或顶部)时,滚动变得迟钝。我在android开发和数据库方面有点新,所以我不知道这是什么原因。

这是我的MainActivity

public class MainActivity extends AppCompatActivity implements CustomAdapter.passing{


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
    setContentView(R.layout.activity_loading);

    db = new DBHandler(this,null,null,1);

    namaDoctor = this.getResources().getStringArray(R.array.namaDokter);

    mHandler.postDelayed(new Runnable() {
        @Override
        public void run() {

            setContentView(R.layout.activity_main);

            searchSpesIcon = (ImageView) findViewById(R.id.buttonSearchSpesial);
            searchRsIcon = (ImageView) findViewById(R.id.buttonSearchRs);
            searchField = (EditText) findViewById(R.id.searchField);
            searchDocIcon = (ImageView) findViewById(R.id.buttonSearchDoctor);
            help = (LinearLayout) findViewById(R.id.help_view);

            searchDocIcon.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    keyword = searchField.getText().toString();
                    query = "SELECT * FROM doctor WHERE nama LIKE '%"+keyword+"%';";
                    namaDoctor = db.searchDoctor(query);
                    id = db.getDoctorId();
                    lokasia = db.getDoctorLokasiA();
                    lokasib = db.getDoctorLokasiB();
                    lokasic = db.getDoctorLokasiC();
                    alamata = db.getDoctorAlamatA();
                    alamatb = db.getDoctorAlamatB();
                    alamatc = db.getDoctorAlamatC();
                    if(tes != namaDoctor.length){
                        change();
                        Toast.makeText(getApplicationContext(),"Hasil pencarian nama dokter " +keyword,Toast.LENGTH_SHORT).show();
                    }else{
                        Toast.makeText(getApplicationContext(),"Tidak ada hasil",Toast.LENGTH_SHORT).show();
                    }

                }
            });

            searchSpesIcon.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    keyword = searchField.getText().toString();
                    query = "SELECT * FROM doctor WHERE spesialisasi LIKE '%"+keyword+"%';";
                    namaDoctor = db.searchDoctor(query);
                    id = db.getDoctorId();
                    lokasia = db.getDoctorLokasiA();
                    lokasib = db.getDoctorLokasiB();
                    lokasic = db.getDoctorLokasiC();
                    alamata = db.getDoctorAlamatA();
                    alamatb = db.getDoctorAlamatB();
                    alamatc = db.getDoctorAlamatC();
                    if(tes != namaDoctor.length){
                        change();
                        Toast.makeText(getApplicationContext(),"Hasil pencarian dokter spesialisasi " +keyword,Toast.LENGTH_SHORT).show();
                    }else{
                        Toast.makeText(getApplicationContext(),"Tidak ada hasil",Toast.LENGTH_SHORT).show();
                    }

                }
            });

            searchRsIcon.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    keyword = searchField.getText().toString();
                    query = "SELECT * FROM doctor " +
                            "WHERE lokasia LIKE '%"+keyword+"%' OR lokasib LIKE '%"+keyword+"%' OR  lokasic LIKE '%"+keyword+"%';";
                    namaDoctor = db.searchDoctor(query);
                    id = db.getDoctorId();
                    lokasia = db.getDoctorLokasiA();
                    lokasib = db.getDoctorLokasiB();
                    lokasic = db.getDoctorLokasiC();
                    alamata = db.getDoctorAlamatA();
                    alamatb = db.getDoctorAlamatB();
                    alamatc = db.getDoctorAlamatC();
                    if(tes != namaDoctor.length){
                        change();
                        Toast.makeText(getApplicationContext(),"Hasil pencarian dokter di rumah sakit " +keyword,Toast.LENGTH_SHORT).show();
                    }else{
                        Toast.makeText(getApplicationContext(),"Tidak ada hasil",Toast.LENGTH_SHORT).show();
                    }
                }
            });

        }
    },milis);

}

void change(){
    if(help.getVisibility()==View.VISIBLE){help.setVisibility(View.GONE);}
    cAdapter = new CustomAdapter(this,namaDoctor,id);
    //use callback
    cAdapter.setPass(this);
    list = (ListView) findViewById(R.id.listContatiner);
    list.setAdapter(cAdapter);
    cAdapter.notifyDataSetChanged();

}

@Override
public void getTag1(int t){
    p1=t;

}

@Override
public void getTag2(int t2) {
    p2=t2;
    setNewAct(p1,p2);
}

public void setNewAct(int x, int y){
  //some method 

}

我的CustomAdapter类

public class CustomAdapter extends ArrayAdapter {

Context c1;
String s1[];
Integer id[];
String spesialisasi[] ;
String daerahPraktek[];
int arrayImageDoctor[] = {R.drawable.doctor_1...};

public CustomAdapter(Context c, String s[], Integer i[]) {
    super(c,R.layout.item_doctor,s);
    this.c1=c;
    this.s1=s;
    this.id=i;
}

private passing pass;

@Override
public View getView(final int position, View v, ViewGroup parent) {
    final LayoutInflater li=(LayoutInflater) c1.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    v = li.inflate(R.layout.item_doctor,null);


    spesialisasi= c1.getResources().getStringArray(R.array.spesialiasiDokter);
    daerahPraktek = c1.getResources().getStringArray(R.array.daerahDokter);

    final TextView nama = (TextView) v.findViewById(R.id.namaDoctor);
    TextView spesial = (TextView) v.findViewById(R.id.spesialisasiDoctor);
    TextView daerah = (TextView) v.findViewById(R.id.daerahPraktekDoctor);
    ImageView ImageDoc = (ImageView) v.findViewById(R.id.imageListDoctor);
    Button lokasi = (Button) v.findViewById(R.id.lokasiPraktek);

    nama.setText(s1[position]);

    spesial.setText("Dokter " + spesialisasi[id[position]]);

    daerah.setText(daerahPraktek[id[position]]);

    ImageDoc.setImageResource(arrayImageDoctor[id[position]]);

    lokasi.setTag(R.id.tag1,id[position]);      
    lokasi.setTag(R.id.tag2,position);

    lokasi.setOnClickListener(new View.OnClickListener() {
            @Override
                public void onClick(View v) {

                int tag = (int) v.getTag(R.id.tag1);
                int pos = (int) v.getTag(R.id.tag2);
                pass.getTag1(tag);
                pass.getTag2(pos);

            }
        });

    return v;
}

public void setPass(passing pass){
    this.pass=pass;
}

public interface passing{
    void getTag1(int t1);
    void getTag2(int t2);
}

我的DBHandler类

public class DBHandler extends SQLiteOpenHelper {

public DBHandler(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
    super(context, DATABASE_NAME, factory, DATABASE_VERSION);
    c=context;
}

@Override
public void onCreate(SQLiteDatabase db) {
    String query = "CREATE TABLE " + TABLE_DOCTOR + "(" +
            COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
            COLUMN_NAMA + " TEXT, " +
            COLUMN_DAERAH + " TEXT, " +
            COLUMN_SPESIALISASI + " TEXT, " +
            COLUMN_LOKASI_A + " TEXT, " +
            COLUMN_LOKASI_B + " TEXT, " +
            COLUMN_LOKASI_C + " TEXT, " +
            COLUMN_ALAMAT_A + " TEXT, " +
            COLUMN_ALAMAT_B + " TEXT, " +
            COLUMN_ALAMAT_C + " TEXT " +");";
    db.execSQL(query);      



        arrayNama = c.getResources().getStringArray(R.array.namaDokter);
        arrayDaerah = c.getResources().getStringArray(R.array.daerahDokter);
        arraySpesialisasi = c.getResources().getStringArray(R.array.spesialiasiDokter);
        arrayLokasiA = c.getResources().getStringArray(R.array.lokasiA);
        arrayLokasiB = c.getResources().getStringArray(R.array.lokasiB);
        arrayLokasiC = c.getResources().getStringArray(R.array.lokasiC);
        arrayAlamatA = c.getResources().getStringArray(R.array.alamatA);
        arrayAlamatB = c.getResources().getStringArray(R.array.alamatB);
        arrayAlamatC = c.getResources().getStringArray(R.array.alamatC);

        ContentValues cv = new ContentValues();

        for (int i = 0; i < arrayNama.length; i++) {
            cv.put(COLUMN_NAMA, arrayNama[i]);
            cv.put(COLUMN_DAERAH, arrayDaerah[i]);
            cv.put(COLUMN_SPESIALISASI, arraySpesialisasi[i]);
            cv.put(COLUMN_LOKASI_A, arrayLokasiA[i]);
            cv.put(COLUMN_LOKASI_B, arrayLokasiB[i]);
            cv.put(COLUMN_LOKASI_C, arrayLokasiC[i]);
            cv.put(COLUMN_ALAMAT_A, arrayAlamatA[i]);
            cv.put(COLUMN_ALAMAT_B, arrayAlamatB[i]);
            cv.put(COLUMN_ALAMAT_C, arrayAlamatC[i]);
            db.insert(TABLE_DOCTOR, null, cv);
        }

}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_DOCTOR);
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_PATIENT);
    onCreate(db);

}   


public String[] searchDoctor(String qdoc){
    SQLiteDatabase db = getWritableDatabase();
    Cursor c= db.rawQuery(qdoc,null);


    String selectedDoc[] = new String[c.getCount()];
    Integer selectedId[] = new Integer[c.getCount()];
    String selectedLokasiA[] = new String[c.getCount()];
    String selectedLokasiB[] = new String[c.getCount()];
    String selectedLokasiC[] = new String[c.getCount()];
    String selectedAlamatA[] = new String[c.getCount()];
    String selectedAlamatB[] = new String[c.getCount()];
    String selectedAlamatC[] = new String[c.getCount()];

    int i = 0;

    while(c.moveToNext()){
        String doc = c.getString(c.getColumnIndex(COLUMN_NAMA));
        Integer id = c.getInt(c.getColumnIndex(COLUMN_ID));
        String lokasia = c.getString(c.getColumnIndex(COLUMN_LOKASI_A));
        String lokasib = c.getString(c.getColumnIndex(COLUMN_LOKASI_B));
        String lokasic = c.getString(c.getColumnIndex(COLUMN_LOKASI_C));

        String alamata = c.getString(c.getColumnIndex(COLUMN_ALAMAT_A));
        String alamatb = c.getString(c.getColumnIndex(COLUMN_ALAMAT_B));
        String alamatc = c.getString(c.getColumnIndex(COLUMN_ALAMAT_C));

        selectedDoc[i]= doc;
        selectedId[i] = id-1;
        selectedLokasiA[i]= lokasia;
        selectedLokasiB[i] = lokasib;
        selectedLokasiC[i] = lokasic;
        selectedAlamatA[i]= alamata;
        selectedAlamatB[i]=alamatb;
        selectedAlamatC[i]= alamatc;

        i++;
    }

    this.doctorId=selectedId;
    this.doctorLokasiA=selectedLokasiA;
    this.doctorLokasiB=selectedLokasiB;
    this.doctorLokasiC=selectedLokasiC;
    this.doctorAlamatA=selectedAlamatA;
    this.doctorAlamatB=selectedAlamatB;
    this.doctorAlamatC=selectedAlamatC;
    return selectedDoc;

}

public Integer[] getDoctorId(){
    return doctorId;
}

public static String[] getDoctorLokasiA() {
    return doctorLokasiA;
}

public static String[] getDoctorLokasiB() {
    return doctorLokasiB;
}

public static String[] getDoctorLokasiC() {
    return doctorLokasiC;
}

public static String[] getDoctorAlamatA() {
    return doctorAlamatA;
}

public static String[] getDoctorAlamatB() {
    return doctorAlamatB;
}

public static String[] getDoctorAlamatC() {
    return doctorAlamatC;
}

和我的Item_doctor.xml

<RelativeLayout
android:id="@+id/itemCLick"
android:background="#0E9EA1"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="15dp">

<ImageView
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:src="@drawable/doctor_1"
    android:id="@+id/imageListDoctor"/>

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:layout_alignParentTop="true"
    android:layout_toRightOf="@+id/imageListDoctor"
    android:layout_toEndOf="@+id/imageListDoctor"
    android:id="@+id/linearLayout">

    <TextView
        android:layout_marginTop="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Nama"
        android:id="@+id/namaDoctor"/>

    <TextView
        android:layout_marginTop="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Spesialis"
        android:id="@+id/spesialisasiDoctor"/>

    <TextView
        android:layout_marginTop="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Daerah"
        android:id="@+id/daerahPraktekDoctor"/>

</LinearLayout>

<Button
    android:layout_width="115dp"
    android:layout_height="wrap_content"
    android:text="Lihat lokasi praktek"
    android:layout_alignBottom="@+id/linearLayout"
    android:layout_alignParentRight="true"
    android:layout_alignParentEnd="true"
    android:id="@+id/lokasiPraktek"
    android:onClick="LokasiPraktek"/>

有人可以告诉我:

1.光标插入数组和Sqlite Query如果没有正确完成会导致大的性能问题吗?

2.列表项目中的视图量是否会影响性能?

3.影响列表视图性能的其他因素是什么?

如果有人告诉我我必须更改代码的哪一部分以提高滚动速度,那将是一件好事。

4 个答案:

答案 0 :(得分:1)

如果您使用自定义ViewHolder并在适配器中实现

,则可以提高列表视图的性能
 @Override
public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder;
        spesialisasi = c1.getResources().getStringArray(R.array.spesialiasiDokter);
        daerahPraktek = c1.getResources().getStringArray(R.array.daerahDokter);
        if (convertView == null) {
            convertView = layoutInflater.inflate(R.layout.item_doctor, parent, false);
            viewHolder = new ViewHolder();

            viewHolder.nama = (TextView) v.findViewById(R.id.namaDoctor);
            viewHolder.spesial = (TextView) v.findViewById(R.id.spesialisasiDoctor);
            viewHolder.daerah = (TextView) v.findViewById(R.id.daerahPraktekDoctor);
            viewHolder.ImageDoc = (ImageView) v.findViewById(R.id.imageListDoctor);
            viewHolder.lokasi = (Button) v.findViewById(R.id.lokasiPraktek);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        viewHolder.nama.setText(s1[position]);

        viewHolder.spesial.setText("Dokter " + spesialisasi[id[position]]);

        viewHolder.daerah.setText(daerahPraktek[id[position]]);

        viewHolder.ImageDoc.setImageResource(arrayImageDoctor[id[position]]);

        viewHolder.lokasi.setTag(R.id.tag1, id[position]);
        viewHolder.lokasi.setTag(R.id.tag2, position);

        viewHolder.lokasi.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                int tag = (int) v.getTag(R.id.tag1);
                int pos = (int) v.getTag(R.id.tag2);
                pass.getTag1(tag);
                pass.getTag2(pos);

            }
        });
        return convertView;
    }


    private class ViewHolder {
        private ImageView ImageDoc;
        private Button lokasi;
        private TextView nama;
        private TextView spesial;
        private TextView daerah;
    }

答案 1 :(得分:0)

您的适配器类的getView方法未正确实现。 将其更改为

@Override
    public View getView(final int position, View v, ViewGroup parent) {
        View row;
        if (v == null) {
            final LayoutInflater li = (LayoutInflater) c1.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row = li.inflate(R.layout.item_doctor, null);
        } else {
            row = v;
        }


        spesialisasi = c1.getResources().getStringArray(R.array.spesialiasiDokter);
        daerahPraktek = c1.getResources().getStringArray(R.array.daerahDokter);

        final TextView nama = (TextView) row.findViewById(R.id.namaDoctor);
        TextView spesial = (TextView) row.findViewById(R.id.spesialisasiDoctor);
        TextView daerah = (TextView) row.findViewById(R.id.daerahPraktekDoctor);
        ImageView ImageDoc = (ImageView) row.findViewById(R.id.imageListDoctor);
        Button lokasi = (Button) row.findViewById(R.id.lokasiPraktek);

        nama.setText(s1[position]);

        spesial.setText("Dokter " + spesialisasi[id[position]]);

        daerah.setText(daerahPraktek[id[position]]);

        ImageDoc.setImageResource(arrayImageDoctor[id[position]]);

        lokasi.setTag(R.id.tag1, id[position]);
        lokasi.setTag(R.id.tag2, position);

        lokasi.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                int tag = (int) v.getTag(R.id.tag1);
                int pos = (int) v.getTag(R.id.tag2);
                pass.getTag1(tag);
                pass.getTag2(pos);

            }
        });

        return row;
    }

答案 2 :(得分:0)

当您滚动以使项目可见时,将调用适配器中的 getView函数。在你写的时候:

final LayoutInflater li=(LayoutInflater) c1.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = li.inflate(R.layout.item_doctor,null);

当您滚动时,视图v将重新布局,从而导致性能下降。您需要通过以下方式检查以重复使用此视图:

        if(v==null) {
            final LayoutInflater li = (LayoutInflater) c1.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v= li.inflate(R.layout.item_doctor, null);
        }

我建议你使用适配器的ViewHolder类。

答案 3 :(得分:0)

尝试以下适配器,并为每个Listview视图设置标签。

public class CustomAdapter extends ArrayAdapter {

Context c1;
String s1[];
Integer id[];
String spesialisasi[] ;
String daerahPraktek[];
int arrayImageDoctor[] = {R.drawable.doctor_1...};

public CustomAdapter(Context c, String s[], Integer i[]) {
    super(c,R.layout.item_doctor,s);
    this.c1=c;
    this.s1=s;
    this.id=i;
}

private passing pass;

@Override
public View getView(final int position, View v, ViewGroup parent) {
    ViewHolder viewHolder = null;
    if(v==null){
    LayoutInflater li=(LayoutInflater) c1.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    v = li.inflate(R.layout.item_doctor,null);
    viewHolder = new ViewHolder();
     viewHolder.nama = (TextView) v.findViewById(R.id.namaDoctor);
    viewHolder.spesial = (TextView) v.findViewById(R.id.spesialisasiDoctor);
    viewHolder.daerah = (TextView) v.findViewById(R.id.daerahPraktekDoctor);
    viewHolder.ImageDoc = (ImageView) v.findViewById(R.id.imageListDoctor);
    viewHolder.lokasi = (Button) v.findViewById(R.id.lokasiPraktek);
    convertView.setTag(viewHolder);
    }else{
    iewHolder = (ViewHolder) convertView.getTag();
    }


    spesialisasi= c1.getResources().getStringArray(R.array.spesialiasiDokter);
    daerahPraktek = c1.getResources().getStringArray(R.array.daerahDokter);



    viewHolder.nama.setText(s1[position]);

    viewHolder.spesial.setText("Dokter " + spesialisasi[id[position]]);

    viewHolder.daerah.setText(daerahPraktek[id[position]]);

    viewHolder.ImageDoc.setImageResource(arrayImageDoctor[id[position]]);

    viewHolder.lokasi.setTag(R.id.tag1,id[position]);      
    viewHolder.lokasi.setTag(R.id.tag2,position);

    viewHolder.lokasi.setOnClickListener(new View.OnClickListener() {
            @Override
                public void onClick(View v) {

                int tag = (int) v.getTag(R.id.tag1);
                int pos = (int) v.getTag(R.id.tag2);
                pass.getTag1(tag);
                pass.getTag2(pos);

            }
        });

    return v;
}
class ViewHolder {
        TextView nama,spesial,daerah;
        Button lokasi;
        ImageView ImageDoc;

    }
public void setPass(passing pass){
    this.pass=pass;
}

public interface passing{
    void getTag1(int t1);
    void getTag2(int t2);
}