0

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

尝试此链接https://stackoverflow.com/a/44842749/1548824 – akhilesh0707

+0

为什么不只是切换到RecyclerView? –

+0

@DivijSehgal RecyclerView给了什么好处。从ListView移动到RecyclerView会很容易吗? –

回答

0

您可以使用多个布局与ListView,所以没有必要马上迁移到RecyclerView ;-)

如果”再通过一个适配器从BaseAdapter莫名其妙地延伸工作,你必须覆盖两个方法:

getViewTypeCount() 

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

getItemViewType(int position) 

获取将被getView(INT,查看,ViewGroup中)指定项目创建视图的类型。

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

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); 
} 
// .... 

,稍后可能会根据View类型的内容变化而使用不同的ViewHolder

通过重写这两种方法,您将使框架尽可能回收View。因此,没有必要检查非空convertView是否具有正确的布局。