Java 我做错了什么?为什么它不起作用?

Java 我做错了什么?为什么它不起作用?,java,android,material-design,Java,Android,Material Design,我遵循了一个教程,它一直工作到当用户按下一个单独的ImageButton时,我按下了该按钮,并且应该更改该图像按钮的背景。这是我从适配器发送到回收器的视图的XML代码 <?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_

我遵循了一个教程,它一直工作到当用户按下一个单独的ImageButton时,我按下了该按钮,并且应该更改该图像按钮的背景。这是我从适配器发送到回收器的视图的XML代码

    <?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/card"
    android:layout_marginBottom="8dp"
    android:padding="16dp"
    app:cardElevation="1dp"
    app:cardCornerRadius="0dp"
    >
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_marginTop="50dp"
        android:weightSum="1">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/mainPost"
            android:textSize="16sp"
            android:layout_marginLeft="4dp"
            android:layout_marginRight="6dp"
            android:text="skjhdjksdfbjkdsbfjksdbjkbjsdkbjfhbsjfbjhdsbfhjsdbfb"/>
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="10dp"
            android:orientation="horizontal"
            android:layout_weight="0.87"
            android:weightSum="2"
            android:id="@+id/relativeCardItem">
<TextView
                android:layout_width="wrap_content"
                android:layout_height="24dp"
                android:textAppearance="?android:attr/textAppearanceListItemSmall"
                android:text="Large Text"
                android:id="@+id/likes"
                android:gravity="left|center_vertical"
                android:layout_centerVertical="true"
                android:layout_marginRight="38dp"
                android:layout_marginEnd="38dp"
                android:layout_alignParentRight="true"/>

            <ImageButton
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:text="New Button"
                android:id="@+id/heart"
                android:layout_alignParentTop="false"
                android:layout_alignParentRight="true"
                android:layout_alignParentEnd="false"
                android:background="@drawable/ic_favorite_outline_24dp"/>

        </RelativeLayout>
    </LinearLayout>


</android.support.v7.widget.CardView>
我也尝试过这个,但当我点击列表项的“收藏夹”按钮时,它会更改单个列表项的背景,但也会更改我未按下的其他列表项的背景图像

@Override
        public void onHeartPress(ImageButton imgB, int pos) {

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                imgB.setBackground(activity.getDrawable(R.drawable.ic_favorite_24dp));
            }
        }
这是我的ViewHolderClass

public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    CardView cardView;
    TextView textView;
    TextView likes;
    ImageButton heart;
    Yammers yammers;
    MyViewclickHolder myViewclickHolder;
    public ViewHolder(View itemView, MyViewclickHolder myViewclickHolder) {
        super(itemView);
        yammers=Yammers.newInstance();
        cardView= (CardView) itemView.findViewById(R.id.card);
        textView= (TextView) itemView.findViewById(R.id.mainPost);
        likes=(TextView) itemView.findViewById(R.id.likes);
        heart= (ImageButton) itemView.findViewById(R.id.heart);
        this.myViewclickHolder=myViewclickHolder;
        heart.setOnClickListener(this);
        cardView.setOnClickListener(this);



    }
    public interface MyViewclickHolder{
        public void onCardPress(CardView cardView, int pos);
        public void onHeartPress(ImageButton imgB, int pos);
    }

    @Override
    public void onClick(View v) {
        if (v instanceof CardView)
        {
            Log.e("View Holder CardView","is pressed at position"+recyclerView.getChildAdapterPosition(v));

            myViewclickHolder.onCardPress((CardView) v, getLayoutPosition());
        }
        else if (v instanceof ImageButton)
        {
            Log.e("View Holder imageButton","is pressed at position"+getLayoutPosition());

            myViewclickHolder.onHeartPress((ImageButton) v,getLayoutPosition());
        }

    }
}
将获得整个视图,而不仅仅是图像按钮。由于封闭布局是CardView,因此您将只获得CardView对象


创建一个界面来捕获图像按钮的点击,然后更改其背景。

这里有几件事要做。当你这么做的时候

ImageButton h= (ImageButton) recyclerView.getChildAt(pos);
它将返回列表项的根布局。在这种情况下,它是一个CardView

这应该是正确的方式去做你正在做的事情

@Override
public void onHeartPress(ImageButton imgB, int pos) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
       imgB.setBackground(activity.getDrawable(R.drawable.ic_favorite_24dp));
    }
}
我单击列表项的“收藏夹”按钮,它将更改 单个列表项的背景,但也会更改 未按的其他列表项的背景图像

@Override
        public void onHeartPress(ImageButton imgB, int pos) {

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                imgB.setBackground(activity.getDrawable(R.drawable.ic_favorite_24dp));
            }
        }
原因是视图回收。这就是RecyclerView所做的。它不会为ArrayList中的每个项目创建视图。相反,它会重新使用先前创建的视图。这就是为什么您总是需要在
onBindViewHolder
方法中更新项目的状态

因此,您将执行以下操作

@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
    try {
          holder.textView.setText(posts.get(position).getString("text"));
          holder.likes.setText(posts.get(position).getString("likes"));
          //update the background of the heart image here based on whether or not 
          //it was ticked

      } catch (JSONException e) {
          e.printStackTrace();
      }
}

您必须维护适配器中已存储的项目。为此,您可以使用

从获取的视图中查找ImagButton

final View rootView = recyclerView.getChildAt(pos);
final ImageButton ibHeart = (ImageButton)   
 rootView.findviewById (R.id.heart);

如果它仍然不适合你。请在您的问题中添加日志。

建议:让您的标题更能描述您正在做的事情好吧,我只是测试一下。对不起,如果我的问题有点混乱,我只是对模糊的标题发表评论,而不是问题的内容好的,谢谢,但是我怎样才能告诉onBindViewHolder更新它呢?我也尝试过这个方法。它也会更新其他列表项的心脏背景。如果您的目的只是更改imageButton的背景,那么您可以在适配器内部进行(尽管这不是合适的标准)和调用notify item changed。当我按下它时,它仍然不起作用更改imagebutton的背景,但仅针对该列表项,其他我没有按下的项也是,因为它是一个recyclerview。相同的视图可以被其他项重用。最好在模型类中维护额外的参数,该参数将定义哪些项被选中,哪些项未被选中,然后可以在适配器上使用notify;然后检查onCreateViewHolder,但现在我得到RelativeLayout$LayoutParams不能转换为android.support.v7.widget.RecyclerView$LayoutParams
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
    try {
          holder.textView.setText(posts.get(position).getString("text"));
          holder.likes.setText(posts.get(position).getString("likes"));
          //update the background of the heart image here based on whether or not 
          //it was ticked

      } catch (JSONException e) {
          e.printStackTrace();
      }
}
final View rootView = recyclerView.getChildAt(pos);
final ImageButton ibHeart = (ImageButton)   
 rootView.findviewById (R.id.heart);