【问题标题】:Performance issue with custom listview in android?android中自定义列表视图的性能问题?
【发布时间】:2014-01-16 06:34:37
【问题描述】:

我使用 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>

【问题讨论】:

  • 您是否在 ListView 中获取所有数据?
  • 是的,我在 listview 中获取所有数据,但是当我滚动时它在 s3 和 s4 中非常慢。
  • 使viewHolder静态化,只需在类前添加静态标识符,public static class viewHolder{ ...... }
  • 我在上课前添加了静态,但同样的事情发生了......它只发生在 Galaxy S3 和 S4 中。某些设备可以正常工作。
  • 嘿,您的问题找到解决方案了吗?

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


【解决方案1】:

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

  • 我发现每次视图为空时都会获取 layoutinflator,因此首先将该代码移动到适配器构造函数并使用该 layoutInflator。
     LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
    

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

  • 要使您的滚动速度更快,您可以使用以下代码:--
         getListView().setFastScrollEnabled(true);
    

    希望这有帮助..享受..!

    更新:-

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

  • 【讨论】:

    • 我使用了这个代码:LayoutInflater inflater; public doctortAdapter() { inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE); },但滚动很慢。
    • getview中layoutinflater的赋值代码你去掉了吗?
    • if (view == null) { view = inflater.inflate(R.layout.custom_list, null);} 我是这样写代码的
    • 好的,您已删除但仍无法正常工作..:?好的,您可以发布您的 xml 代码吗
    【解决方案2】:

    将所有的onclick设置在if之外

    之后:

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

    【讨论】:

      【解决方案3】:

      什么是医生数据列表?它的get方法的时间复杂度是O(1)吗?

      inflating时传入父ViewGroup(但不要添加到根):

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

      不要嵌套 RelativeLayouts,它们会导致指数布局传递,这在 ListView 中确实不好 您的列表视图项的根看起来可以是一个垂直的 LinearLayout,而 Activity 的根可能是一个 FrameLayout,里面有一个 LinearLayout?

      在getItem中返回doctorData_list.get(position)

      在getItemId中返回position

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

      【讨论】:

      • 如果你的医生数据列表很大并且不支持常量时间获取,这可能是你的问题。如果您的 doctorData_list 类似于 ArrayList 它应该没问题,并且使用 UI 线程的其他东西导致它变慢 - 通过这些更改,您的适配器很好
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-14
      • 1970-01-01
      • 2011-07-19
      • 1970-01-01
      相关资源
      最近更新 更多