【问题标题】:Multi-State Toggle Button多状态切换按钮
【发布时间】:2011-06-16 23:14:08
【问题描述】:

在我一直在开发的应用程序中,我希望有一个多状态(在我的情况下是三个)切换按钮,而不是 ToggleButton 提供的两个。我已经尝试开始自己的扩展 Button,遵循 CompoundButton 源,但老实说,阅读它的源有点不知所措。

有没有办法只使用选择器 xml 或其他东西来实现三态切换按钮,或者可能是我没有想到的另一种方法?我不知道如何做到这一点。

【问题讨论】:

    标签: android user-interface button togglebutton


    【解决方案1】:

    您当然可以定义一个选择器用作具有三个条目的背景。问题是您可以为选择器使用哪些按钮属性。您可以有两个布尔属性,例如 A 和 B,并根据 A、B 和默认值定义选择器。 (A && B 将满足 A,因此更恰当地可以将它们视为 A、!A && B 和 !A && !B。)您可以重载现有属性(选择、聚焦等),或者更优雅地,使用in this thread 描述的配方定义您自己的自定义属性。

    【讨论】:

    • 查看您链接的主题:我了解第 1 步,但我有一些问题。在创建新视图时,扩展视图、按钮或其他东西会更好吗?除了构造函数和 onCreateDrawableState() 之外,我还应该重载其他方法吗?如果这些是基本的,我很抱歉,这是我的第一个真正的应用程序。
    • 没关系,让它工作!感谢您朝着正确的方向推动,我很感激。
    • @moonfire 你的代码是专有的吗?我也在尝试创建一个三态切换按钮,并希望看到其他一些解决方案来帮助我了解如何做到这一点。
    • @JohnMetta 抱歉回答晚了,我应该更频繁地查看这里。如果您仍然需要帮助,我刚刚在link 发了一个帖子。或者,如果您只想下载示例源代码:link。希望有帮助!
    【解决方案2】:

    我实现了一个多态切换按钮,源码是here

    看起来是这样的:

    而且使用起来非常简单:

    <org.honorato.multistatetogglebutton.MultiStateToggleButton
        android:id="@+id/mstb_multi_id"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dip"
        mstb:values="@array/planets_array" />
    

    在你的活动中:

    MultiStateToggleButton button2 = (MultiStateToggleButton) this.findViewById(R.id.mstb_multi_id);
    button2.setOnValueChangedListener(new ToggleButton.OnValueChangedListener() {
        @Override
        public void onValueChanged(int value) {
            Log.d(TAG, "Value: " + value);
        }
    });
    

    【讨论】:

    • 你是如何像图片中那样定制它的?在您的文档中,您没有提到任何自定义。
    • 这是旧版本,请尝试搜索旧提交。但基本上你必须修改背景可绘制对象。
    • @jlhonora 感谢您提供这么棒的代码!我想知道是否可以在切换之间进行转换,而不是直接从一个按钮跳到另一个按钮,有没有办法在它们之间进行转换?
    • @jlhonora 如果我将值 Yes 从活动 A 传递到切换按钮所在的 B,我如何将切换按钮的状态设置为选中值 Yes
    【解决方案3】:

    您可以创建一个自定义 ImageButton 来实现此目的,在这种情况下您需要 3 个不同的图像。 如果需要,您还可以添加更多状态。

    public class FlashButton extends ImageButton {
    
        public enum FlashEnum {
            AUTOMATIC, ON, OFF
        }
    
        public interface FlashListener {
            void onAutomatic();
            void onOn();
            void onOff();
        }
    
        private FlashEnum mState;
        private FlashListener mFlashListener;
    
        public FlashButton(Context context, AttributeSet attrs) {
            super(context, attrs);
    
            //Sets initial state
            setState(FlashEnum.AUTOMATIC);
        }
    
    
        @Override
        public boolean performClick() {
            super.performClick();
            int next = ((mState.ordinal() + 1) % FlashEnum.values().length);
            setState(FlashEnum.values()[next]);
            performFlashClick();
            return true;
        }
    
    
        private void performFlashClick() {
            if(mFlashListener == null)return;
            switch (mState) {
                case AUTOMATIC:
                    mFlashListener.onAutomatic();
                    break;
                case ON:
                    mFlashListener.onOn();
                    break;
                case OFF:
                    mFlashListener.onOff();
                    break;
            }
        }
    
        private void createDrawableState() {
            switch (mState) {
                case AUTOMATIC:
                    setImageResource(R.drawable.ic_flash_auto);
                    break;
                case ON:
                    setImageResource(R.drawable.ic_flash_on);
                    break;
                case OFF:
                    setImageResource(R.drawable.ic_flash_off);
                    break;
            }
        }
    
    
        public FlashEnum getState() {
            return mState;
        }
    
        public void setState(FlashEnum state) {
            if(state == null)return;
            this.mState = state;
            createDrawableState();
    
        }
    
        public FlashListener getFlashListener() {
            return mFlashListener;
        }
    
        public void setFlashListener(FlashListener flashListener) {
            this.mFlashListener = flashListener;
        }
    
    }
    

    【讨论】:

    • 你让人变得懒惰 ;)
    【解决方案4】:

    为什么不使用RadioGroup 并在里面设置收音机样式?

     <RadioGroup
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
    
        <RadioButton
            android:layout_width="match_parent"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:background="@drawable/your_drawable_selector"
            android:button="@android:color/transparent"
            android:gravity="center_horizontal" //center text
            android:text="text"
             />
    ...
    

    【讨论】:

      【解决方案5】:

      芯片是一个非常好的原生选项。

       <com.google.android.material.chip.ChipGroup
            android:id="@+id/chip_group"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:singleSelection="true">
      
            <com.google.android.material.chip.Chip
                 android:id="@+id/first_chip"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:gravity="center"
                 android:text="Todo"
                 android:textAppearance="?android:attr/textAppearance"
                 android:textColor="@color/black"
                 android:checkable="true"
                 style="@style/Widget.MaterialComponents.Chip.Choice"
                 app:chipBackgroundColor="@color/colorAccent"/>
      
                 <!-- Second Chip -->
                 <!-- Third Chip -->
      
         </com.google.android.material.chip.ChipGroup>
      

      binding.chipGroup.setOnCheckedChangeListener { chipGroup, i -> 
          when (i) {
              binding.firstChip -> {
                  binding.firstChip.setChipBackgroundColorResource(R.color.colorAccent)
              }
              else -> {} 
          }
      }
      binding.firstChip.isChecked = true  //default
      

      GL

      Source

      【讨论】:

        猜你喜欢
        • 2020-09-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-31
        • 1970-01-01
        相关资源
        最近更新 更多