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

时间:2016-02-16 05:01:49

标签: java android material-design

我已经按照教程here进行操作,直到用户按下按钮时按下单个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>

这是我的适配器代码。

public class IndividualItemsAdapter extends RecyclerView.Adapter<IndividualItemsAdapter.ViewHolder> {
    ArrayList<JSONObject> posts;
    static AppCompatActivity activity;
    static RecyclerView recyclerView;
    private static int current;

    public IndividualItemsAdapter(ArrayList<JSONObject> strings, AppCompatActivity activity, RecyclerView recyclerView) {
        this.posts=strings;
        this.activity=activity;
        this.recyclerView=recyclerView;
    }

    @Override
    public IndividualItemsAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.card_view_element,parent,false);
        Log.e("Recycler", "We are here");
        ViewHolder holder=new ViewHolder(view, new ViewHolder.MyViewclickHolder() {
            @Override
            public void onCardPress(CardView cardView, int pos) {
                FragmentTransaction ft=activity.getSupportFragmentManager().beginTransaction();
                ft.replace(R.id.main,IndividualPosts.newInstance(pos));
                ft.addToBackStack(null);
                ft.commit();

            }

            @Override
            public void onHeartPress(ImageButton imgB, int pos) {
                ImageButton h= (ImageButton) recyclerView.getChildAt(pos);
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    h.setBackground(activity.getDrawable(R.drawable.ic_favorite_24dp));
                }
            }
        });

        return holder;
    }

    @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"));


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


    }
    @Override
    public int getItemCount() {
        return posts.size();
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
    }



    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());
            }

        }
    }

}

我试过这个,但是我得到了类强制转换异常并且无效。

ViewHolder holder=new ViewHolder(view, new ViewHolder.MyViewclickHolder() {
            @Override
            public void onCardPress(CardView cardView, int pos) {
                FragmentTransaction ft=activity.getSupportFragmentManager().beginTransaction();
                ft.replace(R.id.main,IndividualPosts.newInstance(pos));
                ft.addToBackStack(null);
                ft.commit();

            }

            @Override
            public void onHeartPress(ImageButton imgB, int pos) {
            current=recyclerView.getChildAdapterPosition(imgB);
            ImageButton h= (ImageButton) recyclerView.getChildAt(current);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                h.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));
            }
        }

这是我的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());
        }

    }
}

3 个答案:

答案 0 :(得分:0)

  ImageButton h= (ImageButton) recyclerView.getChildAt(pos);

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

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

答案 1 :(得分:0)

这里有几件事情在发挥作用。当你这样做时

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

我点击它更改的列表项的收藏夹按钮   单个列表项的背景,但也改变了   其他列表项目的背景图片,我没有按

原因是View Recycling。这就是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();
      }
}

您必须维护适配器中的哪些项目。为此,您可以使用SparseBooleanArray

答案 2 :(得分:0)

从获取的视图中找到你的ImagButton。

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

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