• Android实现Material Design风格的设置页面(滑动开关控件)


    前言

    本文链接 http://blog.csdn.net/never_cxb/article/details/50763271 转载请注明出处

    參考了这篇文章 Material Design 风格的设置页面

    笔者对原文章做了3个改进:

    • 把勾选框 改成了 Switch 的滑动开关,Material 更彻底

    • 替换后的 SwitchCompat 与整个 Preference 点击事件联动,保存到SharedPreferences

    • 在页面上方添加了 ToolBar,更贴近真实项目场景

    blog.csdn.net/never_cxb

    项目源码地址(欢迎star) https://github.com/studychen/SeeNewsV2

    基础:使用PreferenceScreen和PreferenceCategory

    新建res/xml/preferences.xml 文件

    note: 一定是 xml 目录。不是layout目录

    <?xml version="1.0" encoding="utf-8"?><!--最新栏目的新闻-->
    <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout="@layout/preference_item"
        android:title="@string/title_activity_setting">
    
        <PreferenceCategory
            android:layout="@layout/preference_category_widget"
            android:title="基本设置">
            <CheckBoxPreference
                android:key="@string/save_net_mode"
                android:layout="@layout/preference_item"
                android:summary="仅在Wi-Fi环境下才自己主动载入图片"
                android:title="省流量模式"/>
            <Preference
                android:layout="@layout/preference_item"
                android:summary="删除已缓存的文章内容及图片"
                android:title="清空缓存" />
        </PreferenceCategory>
    
        <PreferenceCategory
            android:layout="@layout/preference_category_widget"
            android:title="其它说明">
            <Preference
                android:layout="@layout/preference_item"
                android:summary="V 1.0"
                android:title="当前版本号" />
            <Preference
                android:layout="@layout/preference_item"
                android:summary="博客:http://blog.csdn.net/never_cxb"
                android:title="TomChen" />
        </PreferenceCategory>
    
    </PreferenceScreen>

    android:layout 实现 Material Design 布局

    上面

    <PreferenceCategory
        android:layout="@layout/preference_category_widget"
        android:title="基本设置">
    ...
    </PreferenceCategory>

    使用android:layout=”@layout/preference_category_widget”改变 PreferenceCategory布局。

    注意 一定要使用系统的id android:id="@android:id/title" `

    <?xml version="1.0" encoding="UTF-8"?

    > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@color/white" android:orientation="vertical"> <TextView android:id="@android:id/title" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingLeft="8dp" android:paddingTop="16dp" android:textColor="@color/primary" android:text="indroduce" android:textSize="14sp" /> </LinearLayout>

    preference_item.xml 定制CheckBoxPreference布局。也就是勾选框(或者滑动开关的布局)

    <?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:minHeight="?

    android:listPreferredItemHeight" android:orientation="horizontal" android:padding="16dp"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1"> <TextView android:id="@android:id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:ellipsize="marquee" android:fadingEdge="horizontal" android:singleLine="true" android:text="title" android:textSize="16sp" /> <TextView android:id="@android:id/summary" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@android:id/title" android:text="summary" android:textColor="#AAAAAA" android:textSize="14sp" /> </RelativeLayout> <LinearLayout android:id="@android:id/widget_frame" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right|center_vertical" android:orientation="vertical"/> </LinearLayout>

    在PreferenceFragment载入设置布局文件

    public class SettingFragment extends PreferenceFragment {
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.preferences);
        }
    }

    这样就实现了原文里的效果图:

    blog.csdn.net/never_cxb

    把CheckBox换成开关控件SwitchCompat

    改动原来xml的CheckBoxPreference

    使用 android:widgetLayout 帮助我们改动CheckBoxPreference布局。
    建立 layout/switch_layout.xml 文件

    <!--此处代码有bug,以下会说明怎样修正-->
    <android.support.v7.widget.SwitchCompat xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textOff="OFF"
        android:textOn="ON" />

    在原来的CheckBoxPreference加上android:widgetLayout="@layout/switch_layout"

    <CheckBoxPreference
        android:key="@string/save_net_mode"
        android:layout="@layout/preference_item"
        android:summary="仅在Wi-Fi环境下才自己主动载入图片"
        android:title="省流量模式"
        android:widgetLayout="@layout/switch_layout" />

    把控件是否选中保存到SharedPreferences中

    设置 android:key="@string/save_net_mode"属性

    Java代码中用getPreferenceManager().findPreference(“key的名称”)来获取

    final CheckBoxPreference checkboxPref = (CheckBoxPreference) getPreferenceManager()
            .findPreference(getString(R.string.save_net_mode));
    
    checkboxPref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
    
        /**
         * @param preference The changed Preference.
         * @param newValue   The new value of the Preference.
         * @return True to update the state of the Preference with the new value.
         */
        @Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            boolean checked = Boolean.valueOf(newValue.toString());
            //保存到SharedPreferences中
            PrefUtils.setSaveNetMode(checked);
            Logger.d("Pref " + preference.getKey() + " changed to " + newValue.toString());
            return true;
        }
    });

    onPreferenceChange 没有调用

    在代码加上了Log输出,可是点击开关控件,却没有反应。

    笔者把android:widgetLayout="@layout/switch_layout"去掉
    使用刚才的CheckBox,点击勾选或者取消勾选。发现能够保存到SharedPreferences

     D/LoggerTag﹕ ║ Pref save_net_mode changed to false
     D/LoggerTag﹕ ║ Pref save_net_mode changed to true

    改动xml的SwitchCompat布局

    添加 android:id="@android:id/checkbox"

    添加

    android:clickable="false"
    android:focusable="false"
    android:focusableInTouchMode="false"

    变成例如以下代码

    <android.support.v7.widget.SwitchCompat xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@android:id/checkbox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:clickable="false"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:textOff="OFF"
        android:textOn="ON" />
    

    这样点击开关button,button开或者关,也能把true或false保存到SharedPreferences中

    添加ToolBar

    新增 layout/setting.xml

    res/xml/preferences.xml中添加ToolBar是不可能的
    由于它的父节点是PreferenceScreen

    我们新建一个 layout/setting.xml
    在这个里面使用Toolbar,以下的FrameLayout展示刚才的设置界面

    <?

    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="match_parent" android:fitsSystemWindows="true" android:orientation="vertical"> <!--Toolbar--> <android.support.v7.widget.Toolbar android:id="@+id/toolbar_preference" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?attr/colorPrimary" android:minHeight="?attr/actionBarSize" /> <FrameLayout android:id="@+id/content_frame" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>

    标题

    使用 getFragmentManager().beginTransaction().replace(,).commit();

    把上面的 FrameLayout替换为SettingFragment extends PreferenceFragment

    public class SettingActivity extends BaseActivity {
    
        @InjectView(R.id.toolbar_preference)
        Toolbar mToolbar;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_setting);
            ButterKnife.inject(this);
            initToolbar();
            getFragmentManager().beginTransaction().replace(R.id.content_frame, new SettingFragment()).commit();
        }
    
    
        /**
         * 初始化Toolbar
         */
        private void initToolbar() {
            mToolbar.setTitle(getResources().getString(R.string.title_activity_setting));
            mToolbar.setTitleTextColor(getResources().getColor(R.color.white));
            setSupportActionBar(mToolbar);
            ActionBar actionBar = getSupportActionBar();
            if (actionBar != null) {
                actionBar.setHomeAsUpIndicator(R.drawable.ic_left_back);
                actionBar.setDisplayHomeAsUpEnabled(true);
            }
        }
    
        /**
         * 选项菜单
         */
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            switch (item.getItemId()) {
                case android.R.id.home:
                    finish();
                    return true;
            }
            return false;
        }
    }
    

    通过 actionBar.setHomeAsUpIndicator(R.drawable.ic_left_back);
    添加了一个返回的白色箭头

    通过 android.R.id.home获取白色箭头的点击事件,返回上一个Activity

    本文链接 http://blog.csdn.net/never_cxb/article/details/50763271 转载请注明出处

    项目源码地址(欢迎star) https://github.com/studychen/SeeNewsV2

    參考文章

  • 相关阅读:
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
    @RequestParam设置默认可以传空值
    python清空列表的方法
    Git分支管理的基本操作
    判断一个坐标点是否在不规则多边形内部的算法
    Flask 解析 Web 端 请求 数组
    SQL server 获取异常
    SQL server 大量数据导入和系统运行慢的问题
    SQL SERVER 跨服务器连接
    #pragma once
  • 原文地址:https://www.cnblogs.com/cxchanpin/p/7353442.html
Copyright © 2020-2023  润新知