使用不同布局时Listview回收

时间:2017-07-10 09:21:53

标签: android android-layout listview android-viewholder recycle

我使用适配器创建了ListView但唯一的问题是我们使用不同的布局,因为它是一个消息传递应用程序。我想通过使用视图回收来提高性能,但无法弄清楚如何回收视图。

是否可以更改视图布局或是否可能:

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        MessageLog message = this.mData.get(position);

        MessageRowViewHolder holder = new MessageRowViewHolder();
        int type = getItemViewType(position);

        switch (type) {
            case TYPE_ITEM:

                // Inflate the correct view depending on whether the message is a reply or
                // own message.
                if (message.isReply()) {
                    convertView = mInflater.inflate(R.layout.row_prisoners_voicemail_message, parent, false);
                } else {
                    convertView = mInflater.inflate(R.layout.row_own_voicemail_message, parent, false);

                }

                // The holder simply holds views for convenient access.
                // It is nothing more than a dumb container.
                holder.type = type;
                holder.position = position;

                holder.messageBackground = (RelativeLayout) convertView.findViewById(R.id.voiceMessageRectangleBackground);

                holder.commentView       = (TextView) convertView.findViewById(R.id.voiceMessageCommentText);
                holder.messageDurationView = (TextView) convertView.findViewById(R.id.voiceMessageDurationText);
                holder.metaTextView      = (TextView) convertView.findViewById(R.id.voiceMessageMetaText);
                holder.timestampView     = (TextView) convertView.findViewById(R.id.voiceMessageTimestampText);

                holder.editButtonView      = (ImageView) convertView.findViewById(R.id.voiceMessageEditButtonImage);
                holder.favouritedImageView = (ImageView) convertView.findViewById(R.id.voiceMessageFavouritedImage);
                holder.playPauseImageView  = (ImageView) convertView.findViewById(R.id.voiceMessagePlayPauseImage);

                // Numeric tags to detect which view has been clicked.
                holder.editButtonView.setTag(position+"");
                holder.metaTextView.setTag(position+"");

                holder.editButtonView.setOnClickListener(this);
                holder.metaTextView.setOnClickListener(this);
                break;
            case TYPE_SEPARATOR:
                convertView = mInflater.inflate(R.layout.grid_date_row, parent, false);

                holder.type = type;
                holder.dateView = (TextView) convertView.findViewById(R.id.date);

                break;
            case TYPE_FILLER:
                convertView = mInflater.inflate(R.layout.grid_filler_row, parent, false);
                holder.type = type;
                holder.dateView = (TextView) convertView.findViewById(R.id.refreshText);

                break;
            case TYPE_ITEM_UPLOAD:
                convertView = mInflater.inflate(R.layout.row_upload_voicemail_message, parent, false);

                holder.type = type;
                holder.messageBackground = (RelativeLayout) convertView.findViewById(R.id.voiceMessageRectangleBackground);
                break;
        }

        // Short-hand notations for the resources and the message date.
        Resources r = context.getResources();
        Date messageDate = message.getDate();

        switch (holder.type) {
            case TYPE_ITEM:

                // Set the duration of the call and the timestamp.
                holder.messageDurationView.setText(PvmUtils.formatMessageDuration(context, message.getDuration()));
                holder.timestampView.setText(PvmUtils.formatMessageTimestamp(messageDate));


                // Set the on click listener for editing.


                // Show/hide the favourited view and comment.
                if (message.isFavourited()) {
                    holder.favouritedImageView.setVisibility(View.VISIBLE);

                    String description = message.getDescription();
                    if (description != null) {
                        holder.commentView.setVisibility(View.VISIBLE);
                        holder.commentView.setText(description);
                    } else {
                        holder.commentView.setVisibility(View.GONE);
                    }

                } else {
                    holder.favouritedImageView.setVisibility(View.INVISIBLE);
                    holder.commentView.setVisibility(View.GONE);
                }


                if (message.isReply()) {
                    // If it is a reply, set the 'NEW' label if it is a new message.
                    if (message.isRead()) {
                        holder.metaTextView.setText("");
                    } else {
                        holder.metaTextView.setText(r.getString(R.string.new_voice_message_label));
                    }

                } else {
                    // If it is own message, set whether the message has been uploaded and
                    // listened to; and if so, when.

                    if (message.isRead()) {

                        String dateRead = "";
                        if (message.getReadAt() != null) {
                            dateRead = PvmUtils.formatMediumLongDate(message.getReadAt());
                        }

                        // E.g. ✓✓ 20 Oct 17 15:54
                        String textToSet = String.format("%s %s", r.getString(R.string.doubleTick), dateRead);
                        holder.metaTextView.setText(textToSet);
                    } else {
                        holder.metaTextView.setText(r.getString(R.string.tick));
                    }
                }

                break;

            case TYPE_SEPARATOR:

                // Just set the formatted date.
                SimpleDateFormat formatDate = new SimpleDateFormat("dd MMM yy (EEE)", SharedResources.getLocale(context));
                holder.dateView.setText(formatDate.format(messageDate));
                break;

            case TYPE_FILLER:

                // Whatever this is...
                int size = list.getHeight();
                holder.dateView.setPadding(0, size/2, 0, size/2);
                break;

            case TYPE_ITEM_UPLOAD:

                // Set the background colour when uploading an item to yellow.
                int colour;
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    colour = r.getColor(R.color.yellow_message, null);
                } else {
                    colour = r.getColor(R.color.yellow_message);
                }

                holder.messageBackground.setBackgroundColor(colour);
                break;
        }

        return convertView;
    }

1 个答案:

答案 0 :(得分:1)

您可以对ListView使用多个布局,因此无需立即迁移到RecyclerView ;-)

如果您正在使用从BaseAdapter以某种方式扩展的适配器,则必须覆盖两种方法:

getViewTypeCount()
  

返回将由getView(int,View,ViewGroup)创建的视图类型数。

getItemViewType(int position)
  

获取将由getView(int,View,ViewGroup)为指定项创建的View类型。

您只需根据需要定义多种不同的视图类型:

private static int VIEW_TYPE_REPLY = 0;
private static int VIEW_TYPE_OTHER = 1;

然后getItemViewType()的实现可能如下所示:

MessageLog message = this.mData.get(position);
if (message.isReply()) {
     return VIEW_TYPE_REPLY;           
} else {
     return VIEW_TYPE_OTHER;      
}

getView()中,可以写

int viewType = getItemViewType(position);
switch(viewType){
    case VIEW_TYPE_REPLY:
        convertView = mInflater.inflate(R.layout.row_prisoners_voicemail_message, parent, false);
        break;
    default:
         convertView = mInflater.inflate(R.layout.row_own_voicemail_message, parent, false);
}
// ....

以后可能会使用不同的ViewHolder,具体取决于View类型的内容有多大差异。

通过覆盖这两种方法,您可以使框架在可能的情况下回收View。因此,没有必要检查非null convertView 是否具有正确的布局。