【问题标题】:java.lang.ClassCastException: android.widget.RelativeLayout$LayoutParams cannot be cast to android.support.v7.widget.RecyclerView$LayoutParamsjava.lang.ClassCastException: android.widget.RelativeLayout$LayoutParams 不能转换为 android.support.v7.widget.RecyclerView$LayoutParams
【发布时间】:2014-12-23 09:39:56
【问题描述】:

我使用android RecycleView 来替换ListLiew。

我想做的是在我的列表项中的一个 ImageView 上启用 onClick(想象这个列表项有一个图像和一个文本,我想向图像添加一个 onClick 侦听器,而不是列表项本身)

我使用以下布局 xml 创建了一个 RecycleView 适配器:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:paddingLeft="16dp"
    android:paddingRight="16dp"
    android:layout_height="48dp"
    android:background="@drawable/border_bottom">

<ImageView
    android:id="@+id/icon"        
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:src="@drawable/ic_action_play_dark"
    android:layout_centerVertical="true" />

<TextView
    android:id="@+id/title"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_marginLeft="56dp"
    android:text="Search"
    android:textColor="#333"
    android:textStyle="bold"
    android:layout_centerVertical="true"  
    android:gravity="center_vertical"/>

</RelativeLayout>

还有我的 onCreateViewHolder

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) 
{
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.drawer_list_item, parent, false);

    ImageView icon = (ImageView)v.findViewById(R.id.icon);
    icon.setOnClickListener(listener);

    PropertyViewHolder vh = new PropertyViewHolder(v);

    return vh;
}

我想将监听器绑定到 ImageView 图标(View 的子项),而不是 View 本身,但是,它总是抛出异常:

12-23 17:37:36.033: E/AndroidRuntime(5806): java.lang.ClassCastException:
android.widget.RelativeLayout$LayoutParams cannot be cast to
android.support.v7.widget.RecyclerView$LayoutParams
at android.support.v7.widget.RecyclerView.getChildPosition(RecyclerView.java:2589)
.....

当我点击图片时,我的 onclickListner 在这里

@Override
public void onClick(View v) {

    int itemPosition = getRecycleView().getChildPosition(v); 

    Toast.makeText(getActivity(), "click ", Toast.LENGTH_SHORT).show();
}

有什么想法吗?

【问题讨论】:

  • 什么时候收到 ClassCastException?
  • 点击图标时(ImageView)
  • 在 getChildPosition(v); v 必须是 RecyclerView 的直接子节点
  • 所以我不能添加 ImageView?
  • 在 ViewHolder 中实现监听器

标签: java android android-recyclerview


【解决方案1】:

从 cmets 中,您可能已经知道它不起作用,因为您的 ImageView 不是位于 RecyclerView 中的视图。

在这种情况下,我建议你在 ViewHolder 中实现监听器,然后在单击图标时传递 ViewHolder 引用而不是 View

我将在下面提供一个示例,


示例 RecyclerView

请注意我是如何在 MyRecyclerViewAdapterMyViewHolder 的构造函数中分配一个侦听器的,它来自 ActivityFragment **。 ActivityFragment 将实现MyViewHolderListener 接口,该接口将提供onIconClicked 方法。

现在请注意,我在 onIconClicked 方法中提供了 MyViewHolder.this 引用。使用该ViewHolder 对象,您可以获得适配器位置,然后最终获得实际的Data 对象。我也提供了onIconClicked 方法的实现。

public class MyRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

private List<Object> mData;

private MyViewHolder.MyViewHolderListener mViewHolderListener;

public MyRecyclerViewAdapter(MyViewHolder.MyViewHolderListener listener) {
    mData = new ArrayList<>();
    mViewHolderListener = listener;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
    return new MyViewHolder(view, mViewHolderListener);
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
    ((MyViewHolder) viewHolder).update(mData.get(position));
}

public void setData(@NonNull List<Object> newData) {
    mData.addAll(newData);
    notifyDataSetChanged();
}

public Object getItemAtPosition(int position) {
    try {
        return mData.get(position);
    } catch (IndexOutOfBoundsException e) {
        e.printStackTrace();
        return null;
    }
}

@Override
public int getItemCount() {
    return mData == null ? 0 : mData.size();
}

public void reset() {
    mData.clear();
    notifyDataSetChanged();
}

public static final class MyViewHolder extends RecyclerView.ViewHolder {

    ImageView icon;

    public MyViewHolder(View itemView, final MyViewHolderListener listener) {
        super(itemView);
        icon = (ImageView) itemView.findViewById(R.id.icon);
        icon.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                listener.onIconClicked(MyViewHolder.this);
            }
        });
    }

    public void update(Object myObject) {
        // update icon
    }

    public interface MyViewHolderListener {
        void onIconClicked(MyViewHolder clickedViewHolder);
    }
}

}


ActivityFragment 内实现OnIconClicked

@Override
public void onIconClicked(MyRecyclerViewAdapter.MyViewHolder clickedViewHolder) {
    int adapterPosition = clickedViewHolder.getAdapterPosition();
    if(adapterPosition != RecyclerView.NO_POSITION) {
        Object selectedItem = mAdapter.getItemAtPosition(adapterPosition);
    }
}

我希望这能解决您的问题!

【讨论】:

    【解决方案2】:

    我在将片段中的 ClickListener 应用到适配器时遇到了这个问题。我发现问题的原因是我在父视图内的嵌套视图上应用了监听器。

    这是我正在使用的应用程序示例。

    <LinearLayout>
        <LinearLayout>
            <ImageView forClickingOn />
        </LinearLayout>
    </LinearLayout>
    

    这是 onClick 实现

    private View.OnClickListener onCompleteClick =
            new View.OnClickListener() {
    
                @Override
                public void onClick(View view) {
                    int iposition = mRecyclerView.getChildLayoutPosition(view);
                    TodoItem item = mAdapter.getItem(iposition);
    
                    item.setCompleted(!item.isCompleted());
    
                    if (item.isCompleted()) {
                        item.setPinned(false);
                    }
    
                    replaceAdapterItem(iposition, item);
                }
            };
    

    我发现解决方案是遍历树回到父元素,将其转换为视图并使用父视图找到位置。

    View rootView = (View) view.getParent() // Frame Layout
            .getParent() // Linear Layout
            .getParent() // Linear Layout
            .getParent(); // Linear Layout
    
    int iposition = mRecyclerView.getChildLayoutPosition(rootView);
    

    我想有更好的方法来找到父元素,但这就是为我解决它的方法。

    【讨论】:

      【解决方案3】:

      通话时

      mRecycleView.getChildLayoutPosition(view) or mRecycleView.getChildAdapterPosition(view),

      参数“view”应该是 RecycleView ItemRootView , 这意味着“视图”是 RecycleView 直接 ChildView。

      所以你的代码

      ImageView icon = (ImageView)v.findViewById(R.id.icon);
      icon.setOnClickListener(listener);
      

      .

      @Override
      public void onClick(View v) {
           //v is the ImageView inside item_layout.
           int itemPosition = getRecycleView().getChildPosition(v); 
           Toast.makeText(getActivity(), "click ", Toast.LENGTH_SHORT).show();
           }
      

      【讨论】:

      • 帮助很大。谢谢。
      【解决方案4】:

      试试这个

          View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.drawer_list_item, (ViewGroup) null, false);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-11-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多