【问题标题】:In Android compound view is not accepting onclick from xml在 Android 复合视图中不接受来自 xml 的 onclick
【发布时间】:2018-08-02 06:46:22
【问题描述】:

我开发了一个自定义复合视图,其中包含 ButtonProgressBar。我在我的应用程序中使用databinding。复合视图不接受onClick事件,这个问题如何排序?

<com.ui.custom.LoadingButton
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/bg_color"
            android:onClick="@{()->viewModel.onNextClick()}"
            android:text="@string/next"
            android:textColor="@color/white"
            app:isLoading="@{viewModel.isLoading}" />

加载按钮布局:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>

    </data>

    <FrameLayout
        android:id="@+id/parentFrame"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <Button
            android:id="@+id/button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?android:selectableItemBackground"
            android:textSize="@dimen/btn_text_size" />

        <com.wang.avi.AVLoadingIndicatorView
            android:id="@+id/loading_indicator"
            android:layout_width="@dimen/btn_loading_indicator"
            android:layout_height="@dimen/btn_loading_indicator"
            android:layout_gravity="center"
            android:elevation="@dimen/cardview_default_elevation"
            app:indicatorName="LineSpinFadeLoaderIndicator" />
    </FrameLayout>
</layout>

或者如果我使用 android 的 'onClick' 属性,那么如何在 TypedArray 中获取它?所以我可以将其设置为以编程方式查看。

   <declare-styleable name="LoadingButton">
        <attr name="isLoading" format="boolean" />
        <attr name="android:text" />
        <attr name="android:textColor" />
        <attr name="android:background" />
        <attr name="android:onClick" />

    </declare-styleable>

加载按钮java

@BindingMethods({
        @BindingMethod(type = LoadingButton.class, attribute = "onLoadingButtonClick", method = "onLoadingButtonClick"),
})
public class LoadingButton extends LinearLayout implements View.OnClickListener {

    private Context mContext;
    private int background, textColor;
    private boolean isLoading;
    private String btnText;
    private LayoutLoadingBtnBinding itemViewBinding;
    private OnLoadingButtonListener listener;

    public LoadingButton(Context context) {
        super(context);
        initializeView(context, null, 0);
    }

    public LoadingButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        initializeView(context, attrs, 0);
    }

    public LoadingButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initializeView(context, attrs, defStyleAttr);
    }

    private void initializeView(Context context, AttributeSet attrs, int defStyleAttr) {
        mContext = context;
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.LoadingButton, defStyleAttr, 0);

        try {
            background = array.getColor(R.styleable.LoadingButton_android_background, Integer.MAX_VALUE);
            textColor = array.getColor(R.styleable.LoadingButton_android_textColor, Integer.MAX_VALUE);
            btnText = array.getString(R.styleable.LoadingButton_android_text);
            isLoading = array.getBoolean(R.styleable.LoadingButton_isLoading, false);
            //   Method onClick = array.getValue(R.styleable.LoadingButton_android_onClick);
        } finally {
            array.recycle();
        }

        itemViewBinding = LayoutLoadingBtnBinding.inflate(LayoutInflater.from(mContext), this, true);

    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();

      //  setOnClickListener(this::onClick);
        setValues();

    }

    private void setValues() {
        try {
            if (background != Integer.MAX_VALUE)
                itemViewBinding.parentFrame.setBackgroundColor(background);

            if (background != Integer.MAX_VALUE) {
                itemViewBinding.button.setTextColor(textColor);
                itemViewBinding.loadingIndicator.setIndicatorColor(textColor);
            }
            itemViewBinding.button.setText(btnText);
            updateLoadingViews();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void updateLoadingViews() {
        itemViewBinding.button.setVisibility(isLoading ? INVISIBLE : VISIBLE);
        itemViewBinding.loadingIndicator.setVisibility(isLoading ? VISIBLE : GONE);
    }

    public void setLoading(boolean isLoading) {
        if (this.isLoading != isLoading)  // update only if loading state is changed
        {
            this.isLoading = isLoading;
            updateLoadingViews();
        }
    }

    public void setOnLoadingButtonClick(OnLoadingButtonListener listener) {
        AppLogger.d("usm_loading_btn_0", "setOnLoadingButtonClick is called: listener= " + (listener != null));
        this.listener = listener;
    }

    @Override
    public void onClick(View view) {
        AppLogger.d("usm_loading_btn_1", "onClick is called");
        if (listener != null) {
            listener.onLoadingButtonClick();
        }
    }

    public interface OnLoadingButtonListener {
        void onLoadingButtonClick();
    }

}

【问题讨论】:

  • 你试过用按钮id来实现onClick监听吗?
  • 父级本身是LinearLayout,我想在它的子级或子级上实现onClick而不访问ids

标签: android android-custom-view android-databinding


【解决方案1】:

你不能用这种方式

<attr name="android:onClick" />

尝试使用BindingMethods

@BindingMethods({
        @BindingMethod(type = LoadingButton.class, attribute = "onLoadingButtonClick", method = "onLoadingButtonClick"),
})
public class LoadingButton extends YOUR_ROOT_VIEW implements View.OnClickListener {
  // your item view class.
  private OnLoadingButtonListener listener;

  public void setOnLoadingButtonClick(OnLoadingButtonListener listener) {
     this.listener = listener;
  }

  @Override
  public void onClick(View view) {
    if (listener != null) {
        listener.onLoadingButtonClick();
    }
  }
  public interface OnLoadingButtonListener {
    void onLoadingButtonClick();
  }
}

在你的布局中

<com.ui.custom.LoadingButton
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/bg_color"
            android:onLoadingButtonClick="@{()->viewModel.onNextClick()}"
            android:text="@string/next"
            android:textColor="@color/white"
            app:isLoading="@{viewModel.isLoading}" />

更新 1

如果您的onClick() 不起作用,请将其删除并尝试以这种方式使用

private void initializeView(Context context, AttributeSet attrs, int defStyleAttr) {
        mContext = context;
        TypedArray array =
                context.obtainStyledAttributes(attrs, R.styleable.LoadingButton, defStyleAttr, 0);

        try {
            background =
                    array.getColor(R.styleable.LoadingButton_android_background, Integer.MAX_VALUE);
            textColor =
                    array.getColor(R.styleable.LoadingButton_android_textColor, Integer.MAX_VALUE);
            btnText = array.getString(R.styleable.LoadingButton_android_text);
            isLoading = array.getBoolean(R.styleable.LoadingButton_isLoading, false);
            //   Method onClick = array.getValue(R.styleable.LoadingButton_android_onClick);
        } finally {
            array.recycle();
        }

        itemViewBinding =
                LayoutLoadingBtnBinding.inflate(LayoutInflater.from(mContext), this, true);
        itemViewBinding.button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (listener != null) {
                    listener.onLoadingButtonClick();
                }
            }
        });
    }

【讨论】:

  • 感谢您的出色解决方案。但是我的 onClick 没有调用,虽然 'setOnLoadingButtonClick' 正常
  • 还是一样... onClick 没有调用
  • itemViewBinding.button再试一次,看看我的更新答案
  • 它在按钮点击上工作,我们可以让它在父视图上工作吗?
  • 我认为是因为你使用了匹配父布局的按钮,所以父视图无法获取点击监听
猜你喜欢
  • 2012-07-16
  • 2013-08-22
  • 1970-01-01
  • 2012-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-07
相关资源
最近更新 更多