0

我阅读了 facebook 开发者博客:https ://www.facebook.com/notes/facebook-engineering/under-the-hood-rebuilding-facebook-for-android/10151189598933920

它说他们正在使用自定义 ListView Recycler 来加快滚动性能。目前,Facebook 原生 Android 应用在滚动和查看大图像方面运行良好。

我想知道如何编写自己的自定义 ListView Recycler?我正在使用 ViewHolder。

这是我的 ArrayAdapter:

public class CampusWallArrayAdapter extends ArrayAdapter<CampusWallModel> {
    private final List<CampusWallModel> list;
    
    class ViewHolder {
        public ImageView ivThumb;
        public TextView display_name;
        public ImageView **ivImage**;
        public ImageView ivImageBackground;
        public TextView time;
        public TextView message;
        public Button bComment;
        public Button bLike;
        public Button bMore;
        public ImageView ivRedDot;
        public ProgressBar pbLoading;
        public RelativeLayout bg;
    }

    public CampusWallArrayAdapter(Context context, List<CampusWallModel> list) {
        super(context, R.layout.campuswallrow, list);
        this.list = list;
    }
    
    public View getView(final int position, View convertView, ViewGroup parent) {
        final ViewHolder holder;
        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) v.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.campuswallrow, null);
            holder = new ViewHolder();
            holder.ivThumb = (ImageView) convertView.findViewById(R.id.ivThumb);
            holder.display_name = (TextView) convertView.findViewById(R.id.display_name);
            **holder.ivImage = (ImageView) convertView.findViewById(R.id.ivImage);**
            holder.ivImageBackground = (ImageView) convertView.findViewById(R.id.ivImageBackground);
            holder.time = (TextView) convertView.findViewById(R.id.time);
            holder.message = (TextView) convertView.findViewById(R.id.message);
            holder.bComment = (Button) convertView.findViewById(R.id.bComment);
            holder.bLike = (Button) convertView.findViewById(R.id.bLike);
            holder.bMore = (Button) convertView.findViewById(R.id.bMore);
            holder.ivRedDot = (ImageView) convertView.findViewById(R.id.ivRedDot);
            holder.pbLoading = (ProgressBar) convertView.findViewById(R.id.pbLoading);
            holder.bg = (RelativeLayout) convertView.findViewById(R.id.bg);
                
            convertView.setTag(holder);
        } else {
            // Get the ViewHolder back to get fast access to the TextView
            // and the ImageView.
            holder = (ViewHolder) convertView.getTag();
        }
        
        //final ViewHolder holder = (ViewHolder) rowView.getTag();
            
            holder.pbLoading.setVisibility(View.GONE);
            holder.ivThumb.setImageBitmap(null);
            holder.ivThumb.setImageDrawable(v.getResources().getDrawable(R.drawable.avatar));
            **holder.ivImage.setImageBitmap(null);**
            holder.ivImageBackground.setBackgroundDrawable(null);
            holder.time.setText("");
            holder.message.setText("");
            holder.bLike.setText("");
            holder.bComment.setText("");
            holder.bComment.setBackgroundResource(R.drawable.button_comment);
            holder.display_name.setText("");
            holder.bLike.setVisibility(View.VISIBLE);
            holder.bLike.setClickable(true);
            holder.bLike.setTextColor(getResources().getColorStateList(R.color.dimgrey3));
            holder.bLike.setBackgroundResource(R.drawable.button_like);
            holder.ivRedDot.setVisibility(View.GONE);
            holder.bMore.setVisibility(View.VISIBLE);
            
            if (list.get(position).display_name == null){
                holder.pbLoading.setVisibility(View.VISIBLE);
                holder.bLike.setVisibility(View.GONE);
                holder.bLike.setClickable(false);
                holder.bComment.setVisibility(View.GONE);
                holder.bComment.setClickable(false);
            } else {
                holder.bLike.setTypeface(Fonts.getOpenSansBold(v.getContext()));
                holder.bLike.setText(String.valueOf(list.get(position).likes));
                if (list.get(position).user_like == -1 || list.get(position).user_like == 0){
                    holder.bLike.setOnClickListener(new Button.OnClickListener() {
                        public void onClick(View v) {
                            list.get(position).likes++;
                            list.get(position).user_like = 1;
                            holder.bLike.setClickable(false);
                            holder.bLike.setText(String.valueOf(list.get(position).likes));
                            holder.bLike.setTextColor(getResources().getColorStateList(R.color.white1));
                            holder.bLike.setBackgroundResource(R.drawable.button_liked);
                            Log.i("like thread invalid", "yes");
                            listView.invalidateViews();
                            
                            // ---------------------- new api for campus wall like ---------------------------------
                            new likeThread(list.get(position).school_thread_id).start();
                        }
                    }); 
                } else if (list.get(position).user_like == 1){
                    holder.bLike.setClickable(false);
                    holder.bLike.setTextColor(getResources().getColorStateList(R.color.white1));
                    holder.bLike.setBackgroundResource(R.drawable.button_liked);
                }
                
                if (list.get(position).thumb_bitmap != null){
                    holder.ivThumb.setImageDrawable(null);
                    holder.ivThumb.setImageBitmap(list.get(position).thumb_bitmap);
                    
                    holder.ivThumb.setOnClickListener(new View.OnClickListener() {
                        public void onClick(View view) {
                            if (!list.get(position).is_anonymous){
                                Bundle extras = new Bundle();
                                extras.putInt("user_id", list.get(position).user_id);
                                Intent i = new Intent(v.getContext(), OthersProfile.class);
                                i.putExtras(extras);
                                startActivity(i);
                            }
                        }
                    });                 
                } 
                
                if (list.get(position).is_anonymous){
                    holder.display_name.setTextColor(getResources().getColorStateList(R.color.black1));
                } else {
                    holder.display_name.setTextColor(getResources().getColorStateList(R.color.blue0));
                }
                holder.display_name.setTypeface(Fonts.getOpenSansBold(v.getContext()));
                holder.display_name.setText(list.get(position).display_name);
                holder.display_name.setOnClickListener(new View.OnClickListener() {
                    public void onClick(View view) {
                        if (!list.get(position).is_anonymous){
                            Bundle extras = new Bundle();
                            extras.putInt("user_id", list.get(position).user_id);
                            Intent i = new Intent(v.getContext(), OthersProfile.class);
                            i.putExtras(extras);
                            startActivity(i);
                        }
                    }
                }); 
                
                if (list.get(position).image_url != null){
                    holder.pbLoading.setVisibility(View.VISIBLE);
                    
                    if (picWidth > 0){
                        int y = picWidth/2;
                        if (imageBg == null){
                            imageBg = new BitmapDrawable(getResources(), NinePatch.getNinePatch(R.drawable.backgroundimage, picWidth, y, v.getContext()));
                        }
                        holder.ivImageBackground.setBackgroundDrawable(imageBg);
                    }
                    
                    if (list.get(position).bitmap != null){
                        if (picWidth > 0){
                            holder.pbLoading.setVisibility(View.GONE);
                            **holder.ivImage.setImageBitmap(list.get(position).RecBitmap);**
                            
                            if (!list.get(position).loaded){
                                //holder.ivImage.startAnimation(AnimationUtils.loadAnimation(getApplicationContext(), R.anim.fade)); //Set animation to your ImageView
                                list.get(position).loaded = true;
                            }                           
                        }
                        
                        holder.ivImage.setOnClickListener(new Button.OnClickListener() {
                            public void onClick(View v) {
                                //Log.i("getWidth", String.valueOf(list.get(position).bitmap.getWidth()) + "/" + String.valueOf((double) picWidth/list.get(position).bitmap.getWidth()));
                                OohlalaMain.tabs.setVisibility(View.GONE);
                                rlBigImage.setVisibility(View.VISIBLE);
                                //tvWords.setText(list.get(position).message);
                                if (list.get(position).bitmap != null){
                                    ivBigImage.setImageBitmap(Bitmap.createScaledBitmap(list.get(position).bitmap, picWidth, (int) (((double) picWidth/list.get(position).bitmap.getWidth())*list.get(position).bitmap.getHeight()), false));           
                                    rlBigImage.setOnClickListener(new Button.OnClickListener() {
                                        public void onClick(View v) {
                                            OohlalaMain.tabs.setVisibility(View.VISIBLE);
                                            rlBigImage.setVisibility(View.GONE);
                                        }
                                    });
                                    pbImageLoading.setVisibility(View.GONE);
                                }
                                /*
                                Bundle extras = new Bundle();
                                extras.putString("image_url", list.get(position).image_url);
                                extras.putString("image_words", list.get(position).message);
                                extras.putInt("picWidth", picWidth);
                                Intent i = new Intent(v.getContext(), CampusWallImage.class);
                                i.putExtras(extras);
                                startActivity(i);
                                */
                            }
                        }); 
                    } else {    
                        if (picWidth > 0){
                            list.get(position).loaded = false;
                        }
                    }
                } else {
                    holder.ivImageBackground.setBackgroundDrawable(null);
                }
                
                holder.time.setTypeface(Fonts.getOpenSansLightItalic(v.getContext()));
                holder.time.setText(list.get(position).added_time);
                holder.message.setTypeface(Fonts.getOpenSansRegular(v.getContext()));
                holder.message.setText(list.get(position).message);
                
                holder.bComment.setText(String.valueOf(list.get(position).comment_count));
                holder.bComment.setTypeface(Fonts.getOpenSansBold(v.getContext()));
                holder.bComment.setOnClickListener(new Button.OnClickListener() {
                    public void onClick(View v) {
                        Bundle extras = new Bundle();
                        extras.putInt("school_thread_id", Integer.parseInt(list.get(position).school_thread_id));
                        extras.putInt("thread_type", thread_type);
                        Intent i = new Intent(v.getContext(), CampusWallComment.class);
                        i.putExtras(extras);
                        startActivity(i);
                        
                        if (list.get(position).num_unread_comments > 0){
                            list.get(position).num_unread_comments = 0;
                            holder.ivRedDot.setVisibility(View.GONE);
                            holder.bComment.setBackgroundResource(R.drawable.button_comment);
                        }
                    }
                }); 
                
                if (list.get(position).num_unread_comments > 0){
                    holder.bComment.setBackgroundResource(R.drawable.button_comment_unread);
                    holder.ivRedDot.setVisibility(View.VISIBLE);
                }
                
                //Log.i("display thread: ", rowView.toString());
                
                if (Profile.userId != list.get(position).user_id){
                    holder.bMore.setVisibility(View.GONE);
                }
                holder.bMore.setOnClickListener(new Button.OnClickListener() {
                    public void onClick(View v) {
                        if (Profile.userId == list.get(position).user_id){
                            showAlertDialog(list.get(position).school_thread_id);
                        }
                    }
                }); 
                
                holder.bg.setOnClickListener(new Button.OnClickListener() {
                    public void onClick(View v) {
                        Bundle extras = new Bundle();
                        extras.putInt("school_thread_id", Integer.parseInt(list.get(position).school_thread_id));
                        extras.putInt("thread_type", thread_type);
                        Intent i = new Intent(v.getContext(), CampusWallComment.class);
                        i.putExtras(extras);
                        startActivity(i);
                        
                        if (list.get(position).num_unread_comments > 0){
                            list.get(position).num_unread_comments = 0;
                            holder.ivRedDot.setVisibility(View.GONE);
                            holder.bComment.setBackgroundResource(R.drawable.button_comment);
                        }
                    }
                }); 
            
            }

            return convertView;
    }

    public void showAlertDialog(final String thread_id) {
        // TODO Auto-generated method stub
        AlertDialog alert = new AlertDialog.Builder(v.getContext()).create();
        alert.setTitle(getString(R.string.Delete_Thread));
        alert.setMessage(getString(R.string.Warning_This_cannot_be_undone));
        alert.setButton(getString(R.string.No), new DialogInterface.OnClickListener() {
            
            public void onClick(DialogInterface dialog, int which) {
                // TODO Auto-generated method stub
            }
        });
        alert.setButton2(getString(R.string.Yes), new DialogInterface.OnClickListener() {
            
            public void onClick(DialogInterface dialog, int which) {
                RestClient result = null;
                try {
                    if (thread_type == 0){
                        result = new Rest.request().execute(Rest.CAMPUS_THREAD + thread_id, Rest.OSESS + Profile.sk, Rest.DELETE).get();
                    } else if (thread_type == 1){
                        result = new Rest.request().execute(Rest.GROUP_THREAD + thread_id, Rest.OSESS + Profile.sk, Rest.DELETE).get();
                    }
                } catch (InterruptedException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                } catch (ExecutionException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                Log.i("delete thread", result.getResponse());
                
                if (result.getResponseCode() == 204){
                    Toast.makeText(v.getContext(), getString(R.string.The_thread_is_deleted), Toast.LENGTH_SHORT).show();
                    refreshAfterPost();
                }
            }
        });
        alert.show();
    }
    
}

list.get(position).thumb_bitmap 和 list.get(position).RecBitmap 都是位图,第一个是较小的位图,第二个是 1024x1024 的大尺寸位图图像文件。

这是我上面 CampusWallArrayAdapter 的 xml 文件(campuswallrow):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/bg"
    android:paddingTop="10dp" 
    android:paddingBottom="5dp"
    android:paddingLeft="10dp"
    android:paddingRight="0dp"
    android:background="@drawable/listview_row_bg_state" >  
  
<ImageView
    android:id="@+id/ivThumb"
    android:layout_width="60dp"
    android:layout_height="60dp"
    android:adjustViewBounds="true" 
    android:scaleType="centerCrop"
    android:layout_marginRight="10dp"
    android:layout_marginBottom="10dp" />

<ImageView
    android:layout_width="60dp"
    android:layout_height="60dp"
    android:adjustViewBounds="true" 
    android:scaleType="centerCrop"
    android:layout_marginRight="10dp"
    android:layout_marginBottom="10dp"
    android:src="@drawable/avatarframe" />

<TextView
    android:id="@+id/display_name"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="aa"
    android:textSize="16dp"
    android:textColor="@color/blue0"
    android:layout_toRightOf="@+id/ivThumb" >
</TextView>

<TextView
    android:id="@+id/message"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"   
    android:text="bb"
    android:textColor="@color/black"
    android:textSize="13dp"
    android:layout_marginRight="10dp"
    android:layout_toRightOf="@+id/ivThumb"
    android:layout_below="@+id/display_name" >
</TextView>

<TextView
    android:id="@+id/time"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="cc"
    android:textColor="@color/dimgrey3"
    android:textSize="13dp"
    android:layout_toRightOf="@+id/ivThumb"
    android:layout_below="@+id/message"
    android:paddingBottom="10dp" >
</TextView>

<ImageView
    android:id="@+id/ivImageBackground"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:scaleType="centerCrop"
    android:adjustViewBounds="true"
    android:layout_below="@+id/time"
    android:layout_marginRight="10dp"
    android:layout_marginBottom="5dp" >
</ImageView>

<ImageView
    **android:id="@+id/ivImage"**
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:scaleType="centerCrop"
    android:adjustViewBounds="true"
    android:layout_below="@+id/time"
    android:layout_marginTop="8dp"
    android:layout_marginLeft="10dp"
    android:layout_marginRight="20dp" />

<ProgressBar
    android:id="@+id/pbLoading"
    style="?android:attr/progressBarStyleSmall"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/time"
    android:layout_centerInParent="true"
    android:layout_marginTop="80dp"
    android:visibility="gone" />
    
    <Button
        android:id="@+id/bComment"
        android:layout_width="65dp"
        android:layout_height="35dp"
        android:text=""
        android:textColor="@color/dimgrey3"
        android:textSize="12dp"
        android:paddingLeft="20dp"
        android:paddingBottom="2dp"
        android:background="@drawable/button_comment"
        android:layout_marginTop="5dp"
        android:layout_marginRight="5dp"
        android:layout_marginBottom="5dp"
        android:layout_below="@+id/ivImageBackground" />
    
    <ImageView
        android:id="@+id/ivRedDot"
        android:layout_width="25dp"
        android:layout_height="29dp"
        android:adjustViewBounds="true" 
        android:scaleType="centerCrop"
        android:layout_marginLeft="45dp"
        android:layout_marginTop="-5dp"
        android:background="@drawable/navbar_notification_nipple"
        android:layout_below="@+id/ivImageBackground"
        android:visibility="gone" />
    
    <Button
        android:id="@+id/bLike"
        android:layout_width="65dp"
        android:layout_height="35dp"
        android:text=""
        android:textColor="@color/dimgrey3"
        android:textSize="12dp"
        android:paddingLeft="25dp"
        android:paddingBottom="2dp"
        android:background="@drawable/button_like"
        android:layout_marginTop="5dp"
        android:layout_marginRight="5dp"
        android:layout_marginBottom="5dp"
        android:layout_below="@+id/ivImageBackground"
        android:layout_toRightOf="@+id/bComment" />
   
    <Button
        android:id="@+id/bMore"
        android:layout_width="60dp"
        android:layout_height="35dp"
        android:layout_alignParentRight="true"
        android:background="@drawable/button_context"
        android:layout_marginRight="10dp"
        android:layout_marginTop="5dp"
        android:layout_below="@+id/ivImageBackground" />

<TextView
    android:id="@+id/unreadcomment"
    android:layout_width="50dp"
    android:layout_height="30dp"
    android:layout_alignParentRight="true"
    android:layout_centerVertical="true"
    android:background="@drawable/list_unread_ribbon"
    android:gravity="center|right"
    android:paddingRight="8dp"
    android:paddingBottom="3dp"
    android:text=""
    android:textColor="@color/white1"
    android:textSize="13dp"
    android:visibility="gone" />

</RelativeLayout>

对于上面的 xml 文件:@+id/ivImage 是我放置主要位图图像的位置。

那么我对 ArrayAdapter 和 ListView 回收器的操作是否正确?有人可以给我一些关于如何使滚动性能更好的提示吗?现在它相当滞后。

谢谢!

4

0 回答 0