I have a RecyclerView in my Fragment, which is populated with several TextInputLayout. After some research, I have managed to set a onClickListener to the TextInputLayout, and is working
BUT
The onClick event is only fired when I tap in the hint of the TextInputLayout. I want it to be fired when I tap in the EditText inside the TextInputLayout.
Code:
In my Fragment:
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 of every "row" in the 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>
This is how I am setting the Listener in the Adapter:
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());
}
}
}
As you can see, I need to do some processing after text is changed in the EditText inside the TextInputLayout. When I have clicked the hint, the afterTextChanged method is fired ok. But to fire the onClick, as I said, I need to click the hint of the TextInputLayout, and is not fired when I simply click the EditText inside. I want to achieve that.
WHAT I HAVE TRIED:
I tried to set the onClickListener on the EditText directly, but it gives an exception.
Is there a way to achieve what I want?
Thank you.
EDIT:
By request, exception when I add the onClickListener on the EditText inside the TextInputLayout:
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)
To get this, I make these changes in the onCreateViewHolder method, inside the adapter:
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;
}
UPDATE:
If I change ViewHolder holder=new ViewHolder(itemView); to ViewHolder holder=new ViewHolder(til);
I receive another kind of Exception:
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)
Just use: TextInputLayout textInputLayout = findViewById(R. id. custom_end_icon); String text = textInputLayout.
The problem is with this line:
TextInputLayout til=(TextInputLayout) rel.getChildAt(0);
in your fragment. The TextInputLayout is not a direct child of RelativeLayout. Try to change it to:
TextInputLayout til=(TextInputLayout)rel.findViewById(R.id.textInputLayout);
Remove below code from onCreateViewHolder:
TextInputLayout til=(TextInputLayout)itemView.getChildAt(0);
EditText editText=til.getEditText();
editText.setOnClickListener(this);
put below code in public ViewHolder(View itemView):
super(itemView);
textInputLayout=(TextInputLayout)itemView.findViewById(R.id.textInputLayout);
EditText text=(EditText)itemView.findViewById(R.id.text);
text.setOnClickListener(this);
Implement OnClickListener
Interface in ViewHolder
Class
In layout file put this line EditText
:
android:focusable="true"
when you click on EditText, it called FocusChangeListener, then again you click then OnClickEvent is Fired. that's why set android:focusable="true"
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With