美文网首页
【原创】基于默认dialog.setSingleChoiceIt

【原创】基于默认dialog.setSingleChoiceIt

作者: 吉凶以情迁 | 来源:发表于2022-04-14 10:13 被阅读0次

    由于强迫症,想不完整定义自定义单选布局对话框就用setSingleChoiceItems实现,于是进行了一些研究,
    经过appcompat包源码分析,AlertController类使用了主题,
    构造函数中


    75769474936c8bf569d5e971b2fc0fe.jpg
        this.mSingleChoiceItemLayout = a.getResourceId(styleable.AlertDialog_singleChoiceItemLayout, 0);
    
        <style name="Base.AlertDialog.AppCompat" parent="android:Widget">
            <item name="android:layout">@layout/abc_alert_dialog_material</item>
            <item name="listLayout">@layout/abc_select_dialog_material</item>
            <item name="listItemLayout">@layout/select_dialog_item_material</item>
            <item name="multiChoiceItemLayout">@layout/select_dialog_multichoice_material</item>
            <item name="singleChoiceItemLayout">@layout/select_dialog_singlechoice_material</item>
            <item name="buttonIconDimen">@dimen/abc_alert_dialog_button_dimen</item>
        </style>
    
    

    单选对话框默认使用的是select_dialog_singlechoice_material
    进一步分析,发现根布局判断是否是checkable,如果改用普通view,则无法实现check效果,因此我用跟布局实现checkable,然后代理事件转发给子viewCheckedTextView实现了转发选中事件的逻辑。

    关于check的逻辑,在AbsListView.updateOnScreenCheckedViews有实现,

    关于 如何找到textview以及修改怎么获取文本内容 的呢?
    实际上是根据adapter的构造函数传递textViewResourceId实现的,因此构造函数进行了一下调整,
    而获取文本内容使用的是泛型类的toString(),所以toString()直接返回标题

    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ArrayAdapter;
    import android.widget.Checkable;
    import android.widget.FrameLayout;
    
    import androidx.annotation.NonNull;
    import androidx.annotation.Nullable;
    
    import com.sotrun.app.R;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    public class ColorSelectAdapter extends ArrayAdapter<ColorSelectAdapter.Bean> {
        public ColorSelectAdapter(@NonNull Context context, int resource) {
            super(context, resource, android.R.id.text1);
        }
    
        public ColorSelectAdapter(@NonNull Context context, int resource, int textViewResourceId) {
            this(context, resource, textViewResourceId, new ArrayList<>());
        }
    
        public ColorSelectAdapter(@NonNull Context context, int resource, @NonNull Bean[] objects) {
            this(context, resource, android.R.id.text1, Arrays.asList(objects));
        }
    
        public ColorSelectAdapter(@NonNull Context context, int resource, int textViewResourceId, @NonNull Bean[] objects) {
            this(context, resource, textViewResourceId, Arrays.asList(objects));
        }
    
        public ColorSelectAdapter(@NonNull Context context, int resource, @NonNull List<Bean> objects) {
            this(context, resource, android.R.id.text1, objects);
        }
    
        public ColorSelectAdapter(@NonNull Context context, int resource, int textViewResourceId, @NonNull List<Bean> objects) {
            super(context, resource, textViewResourceId, objects);
        }
    
    
        @NonNull
        @Override
        public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
            View view = super.getView(position, convertView, parent);
            if (view instanceof CheckableProxyView) {
    
            } else {
                ViewGroup temp = new CheckableProxyView(getContext());
                temp.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT));
                temp.addView(view);
                view = temp;
    
            }
            CheckableProxyView checkableProxyView = (CheckableProxyView) view;
            Checkable tvTitle = view.findViewById(android.R.id.text1);
            checkableProxyView.setCheckNotify(new CheckableProxyView.CheckNotify() {
                @Override
                public void setChecked(boolean checked) {
                    tvTitle.setChecked(checked);
                }
    
                @Override
                public boolean isChecked() {
                    return tvTitle.isChecked();
                }
    
                @Override
                public void toggle() {
                    tvTitle.toggle();
                }
            });
            Bean item = getItem(position);
            View viewColor = view.findViewById(R.id.view_color);
            viewColor.setBackgroundColor(getContext().getResources().getColor(item.color));
            return view;
        }
    
        public static class CheckableProxyView extends FrameLayout implements Checkable {
    
            public CheckableProxyView(Context context) {
                super(context);
            }
    
            public CheckableProxyView(Context context, @Nullable AttributeSet attrs) {
                super(context, attrs);
            }
    
            public CheckableProxyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
                super(context, attrs, defStyleAttr);
            }
    
            public CheckableProxyView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
                super(context, attrs, defStyleAttr, defStyleRes);
            }
    
            @Override
            public void setChecked(boolean checked) {
                if (checkNotify != null) {
                    checkNotify.setChecked(checked);
                }
            }
    
            @Override
            public boolean isChecked() {
                if (checkNotify != null) {
                    return checkNotify.isChecked();
                }
                return false;
            }
    
            @Override
            public void toggle() {
                if (checkNotify != null) {
                    checkNotify.toggle();
                }
            }
    
            public void setCheckNotify(CheckNotify checkNotify) {
                this.checkNotify = checkNotify;
            }
    
            CheckNotify checkNotify;
    
            interface CheckNotify {
                void setChecked(boolean checked);
    
                boolean isChecked();
    
                void toggle();
            }
        }
    
        @Override
        public boolean hasStableIds() {
            return true;
        }
    
        @Override
        public long getItemId(int position) {
            return position;
        }
    
        public static class Bean {
            public int color;
            public String title;
    
            @Override
            public String toString() {
                return title;
            }
        }
    }
    
    
    

    对话框的逻辑

      AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
                    int currentMode = NightModeUtils.Companion.getSpfThemeMode(AppContext.getInstance());
                    ThemeMode[] values = ThemeMode.values();
                    ColorSelectAdapter.Bean[] items=new ColorSelectAdapter.Bean[values.length];
                    for (int i = 0; i < values.length; i++) {
                        String title = AppContext.getInstance().getString(values[i].getStringValueId());
                        ColorSelectAdapter.Bean bean=new ColorSelectAdapter.Bean();
                        bean.title=title;
                        bean.color=values[i].getColor();
                        items[i]=bean;
                    }
                    ColorSelectAdapter arrayAdapter = new ColorSelectAdapter(
                            getActivity(), R.layout.view_color_check_item, items);
                    builder.setSingleChoiceItems(arrayAdapter, currentMode, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            if (which != currentMode) {
                                dialog.dismiss();
                                ThemeMode value = values[which];
                                NightModeUtils.getInstance(AppContext.getInstance()).setThemeMode(value);
                                EventBus.getDefault().post(new ThemeChangeEvent().themeChange());
    
                            }
    
                        }
    
                    });
                    builder.setTitle(AppContext.getStr(R.string.deep_color_theme_setting));
                    builder.show();
    
    

    view_color_check_item.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:orientation="horizontal">
        <View
            android:layout_margin="10dp"
            android:layout_marginRight="0dp"
            android:id="@+id/view_color"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_gravity="center_vertical" />
        <CheckedTextView
            android:id="@android:id/text1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:drawableStart="?android:attr/listChoiceIndicatorSingle"
            android:drawableLeft="?android:attr/listChoiceIndicatorSingle"
            android:drawablePadding="20dp"
            android:ellipsize="marquee"
            android:gravity="center_vertical"
            android:minHeight="?attr/listPreferredItemHeightSmall"
            android:paddingStart="@dimen/abc_select_dialog_padding_start_material"
            android:paddingLeft="@dimen/abc_select_dialog_padding_start_material"
            android:paddingEnd="?attr/dialogPreferredPadding"
            android:paddingRight="?attr/dialogPreferredPadding"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:textColor="?attr/textColorAlertDialogListItem" />
    
    </LinearLayout>
    
    

    相关文章

      网友评论

          本文标题:【原创】基于默认dialog.setSingleChoiceIt

          本文链接:https://www.haomeiwen.com/subject/uphtertx.html