带有按钮的Android自定义视图不可单击

带有按钮的Android自定义视图不可单击,android,android-layout,android-custom-view,android-button,android-inflate,Android,Android Layout,Android Custom View,Android Button,Android Inflate,我已经创建了一个自定义的RelativeLayout视图,并使用merge标记对其进行了充气。 在这个自定义视图中,我有一个按钮,我希望它做一些事情。 我试过很多方法,但是按钮就是不被点击 奇怪的是,我可以很好地找到视图并改变它们的可见性 是否可以通过这种方式单击按钮,还是应该采用其他方式 我尝试过的事情: onClickListener的匿名内部类 单击onClick 使用onClickListener(this) 检查是否可以用代码单击(返回true) 在XML和代码中都添加了clicka

我已经创建了一个自定义的
RelativeLayout
视图,并使用
merge
标记对其进行了充气。
在这个自定义视图中,我有一个按钮,我希望它做一些事情。
我试过很多方法,但是按钮就是不被点击

奇怪的是,我可以很好地找到视图并改变它们的可见性

是否可以通过这种方式单击按钮,还是应该采用其他方式

我尝试过的事情:

  • onClickListener的匿名内部类
  • 单击
    onClick
  • 使用
    onClickListener(this)
  • 检查是否可以用代码单击(返回true)
  • 在XML和代码中都添加了
    clickable(true)
  • 来自构造函数的私有上下文,而不是
    getContext()
  • 将逻辑从
    init()
    移动到
    onFinishInflate()
  • 使用充气机中的视图查找视图
  • 充气()
    切换到
    LayoutInflater
自定义视图:

<?xml version="1.0" encoding="utf-8"?>
<merge
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/internet_view_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="@string/internet_offline"/>

    <custom.IconView
        android:id="@+id/internet_view_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="ICON"
        android:visibility="invisible"
        android:layout_below="@+id/internet_view_text"/>

    <Button
        android:id="@+id/internet_view_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="BUTTON"
        android:clickable="true"
        android:layout_below="@+id/internet_view_text"/>
</merge>

所以我让它工作了。以下是我所做的事情,以使它的工作

  • merge
    标记替换为
    RelativeLayout
    ,因为您正在膨胀布局以在视图中显示。更多信息请点击此处:

  • 您已经设置了
    android:visibility=“invisible”
    ,将其更改为
    android:visibility=“visible”
    (这只是为了让视图可见,您可以稍后通过编程进行更改)

  • 在NoInternetView的init()方法中添加以下行。您正在使用所有视图扩展布局,但只有在添加此视图时才能看到它

    public void init(){
           Log.d(TAG, "init");
           view = LayoutInflater.from(mContext).inflate(R.layout.no_internet_view, this, false);
           this.addView(view);}
    

  • 完成此操作后,按钮将可见,单击按钮将可单击。您可以使用匿名
    onClickListener
    或使视图实现
    onClickListener
    并重写
    onClick()
    方法。任何东西都有效。

    为什么在这里使用合并标记?此处使用的布局仅用于在CustomView中进行充气,此处不需要合并。如果用布局类型替换“合并”是否有效。@Henry我使用了“合并”标记,因为我读过这篇文章,它在层次结构中显示了一个额外的布局,而您不使用“合并”标记。另外,当我将merge更改为RelativeLayout时,我的文本视图和按钮不可见。给我几个小时。我会调试它,并让你们知道。我使用了标签,我得到了一个异常,而充气。请参考此内容以了解为什么不使用:我没有收到任何有关合并的错误消息。此.addView(视图)将导致循环,并最终导致内存不足异常。不完全是这样。您已经创建了一个CustomView,这是一个RelativeLayout。您需要在屏幕上显示一些内容,因此您正在CustomView中放大布局。问题是,单靠通胀是不够的。您需要将该膨胀视图添加到CustomView。我想你在别的地方做错了什么。在做了所有这些修改之后,我运行了你的代码。对我来说很好。这个布局加载到片段布局上有什么区别吗?没有,应该没有什么区别。我没有看到“onFinishInflate”日志,最后一个日志是“Init”。不知何故,这导致了一个循环。我当前的布局如下:活动->片段->自定义布局
    public class NoInternetView extends RelativeLayout implements View.OnClickListener {
    
        private static final String TAG = NoInternetView.class.getSimpleName();
    
        private static ConnectivityChangeListener listener;
        private static boolean automaticReconnect;
        private Context mContext;
        private View view;
    
        private Button button;
    
        public NoInternetView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            mContext = context;
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NoInternetView, defStyleAttr, 0);
            automaticReconnect = a.getBoolean(R.styleable.NoInternetView_automaticReconnect, false);
            a.recycle();
            init();
        }
    
        public NoInternetView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public NoInternetView(Context context) {
            this(context, null);
        }
    
        @Override
        protected void onFinishInflate() {
            Log.d(TAG, "onFinishInflate");
            super.onFinishInflate();
    
            button = (Button) view.findViewById(R.id.internet_view_button);
            button.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    Log.d(TAG, "Clicked on some Button");
                    if (listener != null && NetworkHelper.hasAccess(getContext())) {
                        listener.connected();
                    }
                }
            });
            button.setClickable(true);
    
            boolean clicked = button.callOnClick();
            Log.d(TAG, "clicked: "+clicked);
    
            TextView text = (TextView) view.findViewById(R.id.internet_view_icon);
            text.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    Log.d(TAG, "Clicked on some TextView");
                    if (listener != null && NetworkHelper.hasAccess(getContext())) {
                        listener.connected();
                    }
                }
            });
    
            //check if the attribute 'automaticReconnect' is set to true
            //if so, show an icon instead of a button
            if (automaticReconnect){
                button.setVisibility(INVISIBLE);
                view.findViewById(R.id.internet_view_icon).setVisibility(VISIBLE);
            }
    
        }
    
        public void init(){
            Log.d(TAG, "init");
            view = LayoutInflater.from(mContext).inflate(R.layout.no_internet_view, this, false);
        }
    
        @Override
        public boolean dispatchKeyEvent(KeyEvent event) {
            Log.d(TAG, "something happened?");
            return super.dispatchKeyEvent(event);
        }
    
        @Override
        public void onClick(View v) {
            Log.d(TAG, "Clicked on Button(TextView)");
            if (listener != null && NetworkHelper.hasAccess(getContext())){
                listener.connected();
            }
        }
    
    public void init(){
           Log.d(TAG, "init");
           view = LayoutInflater.from(mContext).inflate(R.layout.no_internet_view, this, false);
           this.addView(view);}