如何在ListView中仅更改一行的Button可见性

时间:2017-10-04 17:45:15

标签: android listview

我已经使用带有自定义适配器的ListView实现了即时消息传递布局。每行显示一条消息和小时。实现列表项的xml包含一个Button(@ + id / alert_button),其可见性已经消失,如果发送的消息出错,该按钮应该可见。

这是xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<RelativeLayout
    android:id="@+id/content"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <RelativeLayout
        android:id="@+id/contentWithBackground"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:id="@+id/risponditore"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="left"
            android:textSize="10sp"
            android:textStyle="bold"
            android:text=""
            android:visibility="gone"
            android:textColor="@color/bluScuro"/>

        <TableLayout
            android:id="@+id/tabellaMessaggioOra"
            android:layout_below="@+id/risponditore"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
            <TableRow
                android:id="@+id/rigaMessaggio"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
                <TextView
                    android:id="@+id/txtMessage"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textColor="@android:color/black"
                    android:maxWidth="245dp"
                    android:textSize="12sp"
                    android:layout_gravity="left"/>
            </TableRow>
            <TableRow
                android:id="@+id/rigaOra"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity ="right">
                <TextView
                    android:id="@+id/ora"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textSize="10sp"
                    android:textColor="@color/grigioScuro"
                    android:layout_gravity="right"/>
            </TableRow>
        </TableLayout>

    </RelativeLayout>

    <Button
        android:id="@+id/alert_button"
        android:layout_toRightOf="@+id/contentWithBackground"
        android:layout_width="15dp"
        android:layout_height="15dp"
        android:layout_marginRight="5dp"
        android:background="@drawable/alert"
        android:layout_centerVertical="true"
        android:visibility="gone"/>
</RelativeLayout>

</RelativeLayout>

这是适配器:

public class ChatAdapter extends BaseAdapter implements 
StickyListHeadersAdapter {
private List<ChatMessage> lista_messaggi_chat;
private static final String DATE_FORMAT_ORA = "HH:mm";//formato h24
private static final String DATE_FORMAT_GIORNO = "dd";
private Context context;
private ViewHolder viewHolder;
//private boolean visibility;

public ViewHolder getViewHolder(){
    return viewHolder;
}

public ChatAdapter(Context context) {
    this.context = context;
    this.lista_messaggi_chat = new ArrayList<>();
}

@Override
public int getCount() {
    return lista_messaggi_chat.size();
}

@Override
public Object getItem(int position) {
    return lista_messaggi_chat.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(final int position, View convertView, ViewGroup parent) 
{
    //Log.i(HoustonConstants.TAG,"ChatAdapter getView");
    //ViewHolder viewHolder;
    LayoutInflater inflater = ((Activity)context).getLayoutInflater();

    if (convertView == null) {
        //The view is not a recycled one: we have to inflate
        convertView = inflater.inflate(R.layout.list_item_message,null);
        viewHolder = createViewHolder(convertView);
        convertView.setTag(viewHolder);
    }else{
        // View recycled !
        // no need to inflate
        // no need to findViews by id
        viewHolder = (ViewHolder) convertView.getTag();
    }

    final ChatMessage messaggio_chat = (ChatMessage)getItem(position);

    if (messaggio_chat.isIncoming()) {
            viewHolder.risponditore.setText(messaggio_chat.getAuthor());
            viewHolder.risponditore.setVisibility(View.VISIBLE);
    }else{
        viewHolder.risponditore.setText("");
        viewHolder.risponditore.setVisibility(View.GONE);
    }
    viewHolder.txtMessage.setText(messaggio_chat.getText());
    viewHolder.ora.setText(getTimeTextOra(messaggio_chat.getTime()));

    if(!messaggio_chat.isIncoming()
     && messaggio_chat == (ChatMessage)getItem(getCount()-1)
     && messaggio_chat.getAlertVisibility()){
        viewHolder.alertButton.setVisibility(View.VISIBLE);
    }


    return convertView;
}

public void add(ChatMessage message) {
    lista_messaggi_chat.add(message);
}

public void add(List<ChatMessage> messages) {
    Collections.sort(messages, new Comparator<ChatMessage>() {
        @Override
        public int compare(ChatMessage lhs, ChatMessage rhs) {
            return lhs.getTime().compareTo(rhs.getTime());
        }
    });
    this.lista_messaggi_chat = messages;
}

private static class ViewHolder {
    public TextView txtMessage;
    public RelativeLayout content;
    public RelativeLayout contentWithBG;
    public TextView ora;
    public TextView giorno;
    public RelativeLayout contenitoreGiorno;
    public TextView risponditore;
    public TableRow rigaOra;
    public TableLayout tabellaMessaggioOra;
    public Button alertButton;
    //public TextView alertMessage;
}

private ViewHolder createViewHolder(View v) {
    ViewHolder holder = new ViewHolder();
    holder.txtMessage = (TextView) v.findViewById(R.id.txtMessage);
    holder.content = (RelativeLayout) v.findViewById(R.id.content);
    holder.contentWithBG = (RelativeLayout) 
v.findViewById(R.id.contentWithBackground);
    holder.ora = (TextView) v.findViewById(R.id.ora);
    holder.giorno = (TextView) v.findViewById(R.id.giorno);
    holder.contenitoreGiorno = (RelativeLayout) 
v.findViewById(R.id.contenitore_giorno);
    holder.risponditore = (TextView) v.findViewById(R.id.risponditore);
    holder.rigaOra = (TableRow) v.findViewById(R.id.rigaOra);
    holder.tabellaMessaggioOra = (TableLayout) 
v.findViewById(R.id.tabellaMessaggioOra);
    holder.alertButton = (Button) v.findViewById(R.id.alert_button);
    //holder.alertMessage = (TextView) v.findViewById(R.id.alert_msg);
    return holder;
}

}

在getView的适配器中,只有当消息不是icoming,如果它是最后一个并且messaggio_chat.getAlertVisibility()返回true,该按钮才会变为可见。我在管理发送错误的活动中将其设置为true,我将消息添加到列表中,按钮可见。

我的问题是该按钮不仅可以显示最后一条消息,还可以随机显示其他消息。

你能告诉我我做错了什么吗?

提前谢谢你。

编辑:

更具体地说,用户可以发送多条消息,并且可能有更多消息在发送时出错,因此我需要在更多行中设置可见警报按钮。然后,如果用户点击一个警报按钮,他可以重新发送一条消息(这尚未实现,但将是下一个)。

1 个答案:

答案 0 :(得分:0)

您正在使用ViewHolder模式并且视图实际上已被回收,因此您不仅要指定它何时必须可见,还必须指定它何时不可见。

if(!messaggio_chat.isIncoming()
 && messaggio_chat == (ChatMessage)getItem(getCount()-1)
 && messaggio_chat.getAlertVisibility()){
    viewHolder.alertButton.setVisibility(View.VISIBLE);
} else {
    viewHolder.alertButton.setVisibility(View.INVISIBLE);
}