我的片段中有一个RecyclerView,其中填充了几个TextInputLayout。经过一些研究,我设法将onClickListener设置为TextInputLayout,并且正在运行
BUT
只有在点击TextInputLayout的提示时才会触发onClick事件。当我点击TextInputLayout中的EditText时,我希望它被触发。
代码:
在我的片段中:
adapter.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.i("Logging", "Element: "+rView.getChildAdapterPosition(v));//rView is RecyclerView
RelativeLayout rel=(RelativeLayout)v;
TextInputLayout til=(TextInputLayout) rel.getChildAt(0);
EditText editText=til.getEditText();
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
Log.i("Logging", "afterTextChanged called");
}
});
}
});
每个"行的XML"在RecyclerView中:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/textInputLayout">
<EditText
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.TextInputLayout>
</RelativeLayout>
这就是我在适配器中设置监听器的方法:
public class IuAdapter extends RecyclerView.Adapter<IuAdapter.ViewHolder> implements View.OnClickListener{
private ArrayList<Model> datos;
private View.OnClickListener listener;
public IuAdapter(ArrayList<Model> datos) {
this.datos = datos;
}
@Override
public void onClick(View v) {
if(listener != null){
listener.onClick(v);
}else{
//Some logging
}
}
public void setOnClickListener(View.OnClickListener listener) {
this.listener = listener;
}
@Override
public IuAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.rowlayout, parent, false);
itemView.setOnClickListener(this);
ViewHolder holder=new ViewHolder(itemView);
return holder;
}
@Override
public void onBindViewHolder(IuAdapter.ViewHolder holder, int position) {
Model item=datos.get(position);
holder.colocarModelo(item);
}
@Override
public int getItemCount() {
return datos.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder{
private TextInputLayout textInputLayout;
public ViewHolder(View itemView) {
super(itemView);
textInputLayout=(TextInputLayout)itemView.findViewById(R.id.textInputLayout);
}
private void colocarModelo(Model model){
textInputLayout.setHint(model.getHint());
textInputLayout.getEditText().setText(model.getValor());
}
}
}
如您所见,我需要在TextInputLayout内的EditText中更改文本后进行一些处理。当我单击提示时,将触发afterTextChanged方法。但是要触发onClick,正如我所说的,我需要单击TextInputLayout的提示,并且当我只是单击里面的EditText时不会触发。我想实现这一点。
我做过什么:
我试图直接在EditText上设置onClickListener,但是它提供了一个异常。
有没有办法达到我想要的目的?
谢谢。
编辑:
根据请求,在TextInputLayout内的EditText上添加onClickListener时出现异常:
java.lang.ClassCastException: android.widget.LinearLayout$LayoutParams cannot be cast to android.support.v7.widget.RecyclerView$LayoutParams
at android.support.v7.widget.RecyclerView.getChildViewHolderInt(RecyclerView.java:3381)
at android.support.v7.widget.RecyclerView.getChildAdapterPosition(RecyclerView.java:3400)
at es.infaplic.gibmov.Fragmentos.IU.GeneralIuFragment$1.onClick(GeneralIuFragment.java:138)
at es.infaplic.gibmov.Adapters.IuAdapter.onClick(IuAdapter.java:33)
at android.view.View.performClick(View.java:4569)
at android.view.View$PerformClick.run(View.java:18553)
at android.os.Handler.handleCallback(Handler.java:743)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5212)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
at dalvik.system.NativeStart.main(Native Method)
为此,我在适配器内的onCreateViewHolder方法中进行了这些更改:
public IuAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
/*View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.rowlayout, parent, false);
itemView.setOnClickListener(this);
ViewHolder holder=new ViewHolder(itemView);*/
RelativeLayout itemView=(RelativeLayout)LayoutInflater.from(parent.getContext())
.inflate(R.layout.rowlayout, parent, false);
TextInputLayout til=(TextInputLayout)itemView.getChildAt(0);
EditText editText=til.getEditText();
editText.setOnClickListener(this);
ViewHolder holder=new ViewHolder(itemView);
return holder;
}
更新:
如果我改变了 ViewHolder holder = new ViewHolder(itemView); 至 ViewHolder holder = new ViewHolder(til);
我收到另一种例外:
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
at android.view.ViewGroup.addViewInner(ViewGroup.java:3562)
at android.view.ViewGroup.addView(ViewGroup.java:3415)
at android.view.ViewGroup.addView(ViewGroup.java:3360)
at android.support.v7.widget.RecyclerView$4.addView(RecyclerView.java:538)
at android.support.v7.widget.ChildHelper.addView(ChildHelper.java:83)
at android.support.v7.widget.RecyclerView$LayoutManager.addViewInt(RecyclerView.java:6079)
at android.support.v7.widget.RecyclerView$LayoutManager.addView(RecyclerView.java:6037)
at android.support.v7.widget.RecyclerView$LayoutManager.addView(RecyclerView.java:6025)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1378)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1327)
at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:556)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:2713)
at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3011)
at android.view.View.layout(View.java:14948)
at android.view.ViewGroup.layout(ViewGroup.java:4631)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1055)
at android.view.View.layout(View.java:14948)
at android.view.ViewGroup.layout(ViewGroup.java:4631)
at android.support.v4.view.ViewPager.onLayout(ViewPager.java:1627)
at android.view.View.layout(View.java:14948)
at android.view.ViewGroup.layout(ViewGroup.java:4631)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1055)
at android.view.View.layout(View.java:14948)
at android.view.ViewGroup.layout(ViewGroup.java:4631)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
at android.view.View.layout(View.java:14948)
at android.view.ViewGroup.layout(ViewGroup.java:4631)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
at android.view.View.layout(View.java:14948)
at android.view.ViewGroup.layout(ViewGroup.java:4631)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
at android.view.View.layout(View.java:14948)
at android.view.ViewGroup.layout(ViewGroup.java:4631)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1991)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1748)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1004)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5703)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
at android.view.Choreographer.doCallbacks(Choreographer.java:574)
at android.view.Choreographer.doFrame(Choreographer.java:544)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
at android.os.Handler.handleCallback(Handler.java:743)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5212)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
at dalvik.system.NativeStart.main(Native Method)
答案 0 :(得分:2)
问题在于这一行:
TextInputLayout til=(TextInputLayout) rel.getChildAt(0);
在你的片段中。 TextInputLayout不是RelativeLayout的直接子节点。尝试将其更改为:
TextInputLayout til=(TextInputLayout)rel.findViewById(R.id.textInputLayout);
答案 1 :(得分:2)
从onCreateViewHolder中删除以下代码:
TextInputLayout til=(TextInputLayout)itemView.getChildAt(0);
EditText editText=til.getEditText();
editText.setOnClickListener(this);
将下面的代码放在公共ViewHolder(查看itemView)中:
super(itemView);
textInputLayout=(TextInputLayout)itemView.findViewById(R.id.textInputLayout);
EditText text=(EditText)itemView.findViewById(R.id.text);
text.setOnClickListener(this);
在OnClickListener
类
ViewHolder
接口
在布局文件中放置此行EditText
:
android:focusable="true"
当您单击EditText时,它调用了FocusChangeListener,然后再次单击,然后OnClickEvent被触发。这就是设置android:focusable="true"
。
答案 2 :(得分:2)
试试这个
public static class ViewHolder extends RecyclerView.ViewHolder{
private TextInputLayout textInputLayout;
private EditText editText;
public ViewHolder(View itemView) {
super(itemView);
textInputLayout=(TextInputLayout)itemView.findViewById(R.id.textInputLayout);
editText=(EditText)itemView.findViewById(R.id.text);
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
private void colocarModelo(Model model){
textInputLayout.setHint(model.getHint());
textInputLayout.getEditText().setText(model.getValor());
}
}
答案 3 :(得分:1)
创建itemview时,不应在onCreateViewHolder方法中将父param传递给inflate方法,将第二个param设置为null
public IuAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
...
RelativeLayout itemView= (RelativeLayout)LayoutInflater.from(parent.getContext())
.inflate(R.layout.rowlayout, parent, false);
使用
RelativeLayout itemView= (RelativeLayout)LayoutInflater.from(parent.getContext())
.inflate(R.layout.rowlayout, null, false);
答案 4 :(得分:1)
@Override
public IuAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.rowlayout, parent, false);
EditText text=(EditText)itemView.findViewById(R.id.text);
text.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
}
});
return holder;
}