[英]java.lang.ClassCastException: android.widget.RelativeLayout$LayoutParams cannot be cast to android.support.v7.widget.RecyclerView$LayoutParams
I using android RecycleView to replace ListLiew. 我使用android RecycleView来替换ListLiew。
What I wanna do is to enabled onClick on one of the ImageView in my List Item (imaging this List item got a image and a text, I want to add a onClick listener to the image but not the list item itself) 我想做的是在我的列表项中的一个ImageView上启用onClick(成像此List项有一个图像和一个文本,我想为图像添加一个onClick监听器,但不是列表项本身)
I create one RecycleView Adapter with following layout xml: 我创建了一个具有以下布局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>
and my onCreateViewHolder 和我的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;
}
I want to bind the listener to the ImageView icon (child of the View), but not the View itself, however, it always throw exception : 我想将侦听器绑定到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)
.....
when I click on the image, my onclickListner here 当我点击图片时,我的onclickListner在这里
@Override
public void onClick(View v) {
int itemPosition = getRecycleView().getChildPosition(v);
Toast.makeText(getActivity(), "click ", Toast.LENGTH_SHORT).show();
}
any idea ? 任何的想法 ?
From the comments, you may already know that it's not working because your ImageView
is not the view which resides in the RecyclerView
. 从评论中,您可能已经知道它不起作用,因为您的
ImageView
不是驻留在RecyclerView
的视图。
In this case, I would suggest you to implement listener in the ViewHolder, and then pass ViewHolder
reference when icon is clicked rather than it's View
在这种情况下,我建议你在ViewHolder中实现监听器,然后在单击图标时传递
ViewHolder
引用,而不是它的View
I will provide an example below, 我将在下面提供一个例子,
Notice how I've assigned a listener in the constructor of both MyRecyclerViewAdapter
and MyViewHolder
which comes from either an Activity
or Fragment
**. 注意我是如何在
MyRecyclerViewAdapter
和MyViewHolder
的构造函数中分配一个侦听器,它来自Activity
或Fragment
**。 That Activity
or Fragment
will implement MyViewHolderListener
interface which will provide onIconClicked
method. 该
Activity
或Fragment
将实现MyViewHolderListener
接口,该接口将提供onIconClicked
方法。
Now notice that, I am providing MyViewHolder.this
reference in the onIconClicked
method. 现在请注意,我在
onIconClicked
方法中提供了MyViewHolder.this
引用。 Using that ViewHolder
object, you can get adapter position and then actual Data
object eventually. 使用该
ViewHolder
对象,您可以最终获得适配器位置,然后获取实际的Data
对象。 I have provided implementation of onIconClicked
method, too. 我也提供了
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);
}
}
} }
OnIconClicked
inside an Activity
or a Fragment
Activity
或Fragment
实现OnIconClicked
@Override
public void onIconClicked(MyRecyclerViewAdapter.MyViewHolder clickedViewHolder) {
int adapterPosition = clickedViewHolder.getAdapterPosition();
if(adapterPosition != RecyclerView.NO_POSITION) {
Object selectedItem = mAdapter.getItemAtPosition(adapterPosition);
}
}
I hope this solves your query! 我希望这能解决你的问题!
I ran into this problem when applying a ClickListener from the Fragment into the Adapter. 从Fragment将ClickListener应用到适配器时遇到了这个问题。 I found that the cause of the issue was that I was applying a listener on a nested view within the parent view.
我发现问题的原因是我在父视图中的嵌套视图上应用了一个监听器。
Here's an example of an application that I'm working, eg. 这是我正在使用的应用程序的示例,例如。
<LinearLayout>
<LinearLayout>
<ImageView forClickingOn />
</LinearLayout>
</LinearLayout>
This is the onClick implementation 这是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);
}
};
I found the solution was the traverse the tree back to the parent element, cast it as a View and find the position using the parent View. 我发现解决方案是将树遍历回父元素,将其转换为视图并使用父视图查找位置。
View rootView = (View) view.getParent() // Frame Layout
.getParent() // Linear Layout
.getParent() // Linear Layout
.getParent(); // Linear Layout
int iposition = mRecyclerView.getChildLayoutPosition(rootView);
I imagine that there's better way of finding the parent element, but this is what solved it for me. 我想有更好的方法来找到父元素,但这就是我解决它的原因。
when call 打电话时
mRecycleView.getChildLayoutPosition(view) or mRecycleView.getChildAdapterPosition(view)
, mRecycleView.getChildLayoutPosition(view) or mRecycleView.getChildAdapterPosition(view)
,
the parameter "view" should be RecycleView ItemRootView , it's mean "view" is RecycleView direct ChildView. 参数“view”应该是RecycleView ItemRootView,它的意思是“视图”是RecycleView直接的ChildView。
so your code 所以你的代码
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();
}
试试这个
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.drawer_list_item, (ViewGroup) null, false);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.