Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OnClick in the EditText inside TextInputLayout, inside a RecyclerView

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)
like image 447
Fustigador Avatar asked Jun 24 '16 11:06

Fustigador


People also ask

How do I get TextInputLayout from text?

Just use: TextInputLayout textInputLayout = findViewById(R. id. custom_end_icon); String text = textInputLayout.


2 Answers

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

like image 150
R. Zagórski Avatar answered Oct 01 '22 13:10

R. Zagórski


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".

like image 44
Asif Patel Avatar answered Oct 01 '22 14:10

Asif Patel