android中自定义listview的性能问题?

时间:2014-01-16 06:34:38

标签: android performance android-listview android-custom-view

我使用View-Holder类来显示自定义列表视图。在Galaxy S3,S4等设备中,滚动列表视图会非常慢。在某些设备中它非常快。我不知道它为什么不能快速滚动在S3和S4中。请任何人帮助我。

我的代码是:

public class doctortAdapter extends BaseAdapter {

        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return doctorData_list.size();
        }

        @Override
        public Object getItem(int position) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public long getItemId(int position) {
            // TODO Auto-generated method stub
            return 0;
        }

        @Override
        public View getView(final int position, View convertView,
                ViewGroup parent) {
            // TODO Auto-generated method stub

            View view = convertView;
            final RecordHolder holder;
            if (view == null) {
                LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
                view = inflater.inflate(R.layout.custom_list, null);

                holder = new RecordHolder();

                holder.txtName = (TextView) view
                        .findViewById(R.id.textView_name);
                holder.txtAddress1 = (TextView) view
                        .findViewById(R.id.textView_address);
                holder.txtAddress2 = (TextView) view
                        .findViewById(R.id.textView_address1);
                holder.btn_book = (Button) view.findViewById(R.id.button_book);
                holder.btn_advice = (Button) view
                        .findViewById(R.id.button_advice);
                holder.btn_favourite = (Button) view
                        .findViewById(R.id.button_faviourate);
                holder.txtReview = (TextView) view.findViewById(R.id.textView2);
                holder.img_personPic = (ImageView) view
                        .findViewById(R.id.imageView1);
                holder.rt = (RatingBar) view.findViewById(R.id.ratingBar1);
                holder.btn_book.setFocusable(false);
                holder.btn_advice.setFocusable(false);
                holder.btn_favourite.setFocusable(false);
                holder.rt.setFocusable(false);

                holder.rt.setOnTouchListener(new OnTouchListener() {

                    @Override
                    public boolean onTouch(View v, MotionEvent event) {
                        // TODO Auto-generated method stub

                        if (event.getAction() == MotionEvent.ACTION_UP) {
                            DoctorData doc_data = doctorData_list.get(position);
                            selected_doctorID = doc_data.getDocID();

                            if (checkSession() == true) {
                                addReview();
                            } else {
                                ratingBarDialog();
                            }
                        }

                        return true;
                    }
                });

                holder.btn_favourite.setOnClickListener(new OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        // TODO Auto-generated method stub

                        DoctorData doc_data = doctorData_list.get(position);
                        doctorid = doc_data.getDocID();
                        if (checkSession() == true) {
                            favouriteDialog();
                        } else {
                            // ratingBarDialog();
                            signInDialog();
                        }

                    }
                });

                holder.btn_book.setOnClickListener(new OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        // TODO Auto-generated method stub
                        DoctorData doc_data = doctorData_list.get(position);
                        startActivity(new Intent(MainActivity.this,
                                DoctorDetailsActivity.class).putExtra(
                                "doctorData", doc_data).putExtra(
                                "TabSelection", "schedule"));
                        Editor prefsEditor = pref.edit();
                        Gson gson = new Gson();
                        String json = gson.toJson(doc_data);
                        prefsEditor.putString("doctorData", json);
                        prefsEditor.commit();
                        finish();


                    }
                });

                holder.btn_advice.setOnClickListener(new OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        // TODO Auto-generated method stub
                        startActivity(new Intent(MainActivity.this,
                                FreeAdviceActivity.class));
                        finish();
                    }
                });

                holder.txtReview.setOnClickListener(new OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        // TODO Auto-generated method stub
                        DoctorData doc_data = doctorData_list.get(position);
                        startActivity(new Intent(MainActivity.this,
                                DoctorDetailsActivity.class).putExtra(
                                "doctorData", doc_data).putExtra(
                                "TabSelection", "review"));
                        Editor prefsEditor = pref.edit();
                        Gson gson = new Gson();
                        String json = gson.toJson(doc_data);
                        prefsEditor.putString("doctorData", json);
                        prefsEditor.commit();
                        finish();
                    }
                });

                view.setTag(holder);
            } else {
                holder = (RecordHolder) view.getTag();
            }

            DoctorData doc_data = doctorData_list.get(position);
            holder.txtName.setText(doc_data.getFirstName() + " "
                    + doc_data.getLastName());
            holder.txtAddress1.setText(doc_data.getAddress1());
            holder.txtAddress2.setText(doc_data.getAddress2());

            return view;
        }

    }

    public class RecordHolder {
        TextView txtName, txtAddress1, txtAddress2, txtReview;
        ImageView img_personPic;
        Button btn_book, btn_favourite, btn_advice;
        RatingBar rt;
    }

自定义列表视图代码:

<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"
    tools:context=".MainActivity" >

    <RelativeLayout
        android:id="@+id/relativeLayout1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true" >

        <ImageView
            android:id="@+id/imageView1"
            android:layout_width="80dp"
            android:layout_height="70dp"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="5dp"
            android:src="@drawable/defaultprofilepic" />

        <TextView
            android:id="@+id/textView_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignTop="@+id/imageView1"
            android:layout_marginLeft="16dp"
            android:layout_toRightOf="@+id/imageView1"
            android:text="No Name"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:textStyle="bold" />

        <LinearLayout
            android:id="@+id/linearLayout1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/imageView1"
            android:layout_alignParentRight="true"
            android:layout_below="@+id/textView2"
            android:layout_marginRight="10dp"
            android:layout_marginTop="5dp"
            android:orientation="horizontal"
            android:weightSum="2" >

            <Button
                android:id="@+id/button_advice"
                style="@style/buttons"
                android:layout_width="wrap_content"
                android:layout_alignLeft="@+id/imageView1"
                android:layout_below="@+id/imageView1"
                android:layout_weight="1"
                android:text="Free Advice" />

            <Button
                android:id="@+id/button_book"
                style="@style/buttons"
                android:layout_width="wrap_content"
                android:layout_alignTop="@+id/button_faviourite"
                android:layout_marginLeft="5dp"
                android:layout_toRightOf="@+id/button_faviourite"
                android:layout_weight="1"
                android:text="$0 Book 0nline" />
        </LinearLayout>

        <TextView
            android:id="@+id/textView_address"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/textView_name"
            android:layout_below="@+id/textView_name"
            android:layout_marginTop="3dp"
            android:maxLines="2"
            android:text="No address"
            android:textAppearance="?android:attr/textAppearanceSmall" />

        <TextView
            android:id="@+id/textView_address1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/textView_name"
            android:layout_below="@+id/textView_address"
            android:layout_marginTop="3dp"
            android:text="No address"
            android:textAppearance="?android:attr/textAppearanceSmall" />

        <RatingBar
            android:id="@+id/ratingBar1"
            style="@style/foodRatingBar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/textView_address1"
            android:layout_below="@+id/textView_address1"
            android:layout_marginTop="5dp" />

        <Button
            android:id="@+id/button_faviourate"
            android:layout_width="20dp"
            android:layout_height="20dp"
            android:layout_alignRight="@+id/linearLayout1"
            android:layout_alignTop="@+id/textView_name"
            android:background="@drawable/favoirate_selector" />

        <TextView
            android:id="@+id/textView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBottom="@+id/ratingBar1"
            android:layout_alignRight="@+id/linearLayout1"
            android:text="Reviews"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:textColor="#07a3d3" />

    </RelativeLayout>

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/relativeLayout1"
        android:layout_marginLeft="100dp"
        android:text="TextView"
        android:visibility="invisible" />

</RelativeLayout>

和mainActicity:

<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"
    tools:context=".MainActivity" >

    <TableLayout
        android:id="@+id/tableLayout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true" 
        android:layout_marginTop="5dp">

        <TableRow
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" >

            <ImageView
                android:id="@+id/imageView1"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_weight="1"
                android:src="@drawable/doctor" />

            <ImageView
                android:id="@+id/imageView2"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_weight="1"
                android:src="@drawable/location" />

            <ImageView
                android:id="@+id/imageView3"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_weight="1"
                android:src="@drawable/insurance" />
        </TableRow>
 </TableLayout>

 <TableLayout
     android:id="@+id/tableLayout1"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:layout_alignParentRight="true"
     android:layout_below="@+id/tableLayout" >

        <TableRow
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" >

            <TextView
                android:id="@+id/textView1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="center"
                android:text="Speciality"
                android:textAppearance="?android:attr/textAppearanceSmall" />

            <TextView
                android:id="@+id/textView2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="center"
                android:text="Location"
                android:textAppearance="?android:attr/textAppearanceSmall" />

            <TextView
                android:id="@+id/textView3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="center"
                android:text="Small Text"
                android:visibility="invisible"
                android:textAppearance="?android:attr/textAppearanceSmall" />
        </TableRow>
    </TableLayout>

    <RelativeLayout
        android:id="@+id/relativeLayout1"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/tableLayout1"
        android:layout_marginTop="5dp"
        android:background="@drawable/new_header" >

        <TextView
            android:id="@+id/textView_date"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:text="Small Text"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:textStyle="bold" />

        <Button
            android:id="@+id/button_privious"
            style="?android:attr/buttonStyleSmall"
            android:layout_width="30dp"
            android:layout_height="40dp"
            android:layout_alignBaseline="@+id/textView_date"
            android:layout_alignBottom="@+id/textView_date"
            android:layout_alignParentLeft="true"
            android:layout_marginLeft="10dp"
            android:background="@drawable/leftarrow" />

        <Button
            android:id="@+id/button_next"
            style="?android:attr/buttonStyleSmall"
            android:layout_width="30dp"
            android:layout_height="40dp"
            android:layout_alignBaseline="@+id/textView_date"
            android:layout_alignBottom="@+id/textView_date"
            android:layout_alignParentRight="true"
            android:layout_marginRight="10dp"
            android:background="@drawable/rightarrow" />

        <ImageView
            android:id="@+id/imageView_date"
            android:layout_width="40dp"
            android:layout_height="30dp"
            android:layout_centerVertical="true"
            android:layout_marginRight="15dp"
            android:layout_toLeftOf="@+id/button_next"
            android:src="@drawable/calendar" />

    </RelativeLayout>

    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="70dp"
        android:layout_above="@+id/button_next_call1"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/relativeLayout1" >

    </ListView>

    <ProgressBar
        android:id="@+id/progressBar1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:indeterminateDrawable="@drawable/my_custom_progresswheel"
        android:visibility="invisible"
        />

    <Button
        android:id="@+id/button_next_call1"
        android:layout_width="60dp"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_margin="5dp"
        android:text="Next" 
        android:textColor="#ffffff"
        android:background="@drawable/customborder_backbutton"/>

    <Button
        android:id="@+id/button_previous"
        android:layout_width="80dp"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_margin="5dp"
        android:text="Previous" 
        android:textColor="#ffffff"
        android:visibility="invisible"
        android:background="@drawable/customborder_backbutton" />

</RelativeLayout>

3 个答案:

答案 0 :(得分:1)

我检查了你的代码,我发现: -

  • 我发现每次视图为null时都会获取layoutinflator,所以首先将该代码移动到适配器构造器并使用该layoutInflator。

     LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
    

    将其声明为适配器类的实例变量,然后使用它。

  • 要快速滚动,您可以使用以下代码: -

         getListView().setFastScrollEnabled(true);
    

    希望这有助于..祝你......!

    更新: -

    我检查了你的xml和你的代码,一切都很好我认为问题是你的listview行有很多视图,你得到findviewbyid()需要一些时间,所以可能你需要优化那些。移动那些视图findViewById( )你没有用于显示。

  • 答案 1 :(得分:0)

    将所有onclick设置为if

    之后:

      } else {
                    holder = (RecordHolder) view.getTag();
                }
      //set all the onClick listener
    

    答案 2 :(得分:0)

    什么是doctorData_list?它的get方法的时间复杂度是O(1)?

    在充气时传递父ViewGroup(但不要将其添加到根目录):

    view = inflater.inflate(R.layout.custom_list, parent, false);
    

    不要嵌套RelativeLayouts,它们会导致指数布局传递,这在ListView中真的不太好 listview项的根看起来像是一个垂直的LinearLayout,而Activity的根可能是一个内部有LinearLayout的FrameLayout吗?

    doctorData_list.get(position)

    中返回getItem

    position

    中返回getItemId

    将位置保存到if(view == null)/else条件之外的视图标记中。从传递给这些方法的视图中的onClickonTouch等方法中读取该标记。 目前,您的按钮将使用首次创建视图的位置 - 如果向下滚动并且它们被回收,当您单击位置X中的某些内容时,它将更新不同位置的数据。