OnClick在RecyclerView内的TextInputLayout内的EditText中

时间:2016-06-24 11:36:30

标签: android android-recyclerview android-textinputlayout

我的片段中有一个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)

5 个答案:

答案 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;

}