设置界面 通用系列
· 减少重复性代码,快速搭建设置界面(通过简单的配置,就可以达到想要的布局);

· 设置界面大同小异,无非由标题,内容,图标等元素组成;
· 既然每一个设置项都有Title,那么就用Title的strId来作为它的唯一标识(便于点击等处理);
· 复杂的地方在分割线的处理方式上(是整行显示,还是不要显示,又或者是在图像后面显示);
· 继承自LinearLayout,要可以添加分割线,可以添加tips提示;
<string name="app_name_0">用户名</string><?xml version="1.0" encoding="utf-8"?><com.lyloou.android.view.SettingLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/svg_set"android:background="#dedede"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical" />
// 找到SettingLayoutSettingLayout sl = (SettingLayout) findViewById(R.id.svg_set);SettingLayout.Item item_0 = new SettingLayout.Item(int titleStrId, int iconResId, String contentStr, String unitStr, boolean hasToRight, SEP sep,IClickListener listener);sl.addItem(item_0);// 也可以对item_0 进行单独的设置最后通过`sl.refreshItem(item_0)`来使设置生效;

★ 定义文字资源(strings.xml)
<resources><string name="app_name">Lou</string><string name="app_name_0">用户名</string><string name="app_name_0_1">身高</string><string name="app_name_0_2">体重</string><string name="app_name_1">双卡和网络</string><string name="app_name_2">无线网络</string><string name="app_name_3">蓝牙</string><string name="app_name_4">其他连接方式</string><string name="app_name_5">通知栏和状态栏</string><string name="app_name_6">声音和振动</string><string name="app_name_7">免打扰</string><string name="app_name_8">系统音效</string><string name="app_name_9">触摸反馈</string><string name="app_name_10">短信铃声</string><string name="app_name_11">朋友圈</string><string name="app_name_12">扫一扫</string><string name="app_name_13">摇一摇</string><string name="app_name_14">购物</string><string name="app_name_15">游戏</string></resources>
★ 设置布局文件(activity_setting.xml)
<?xml version="1.0" encoding="utf-8"?><ScrollView xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#dedede" ><com.lyloou.android.view.SettingLayoutandroid:id="@+id/svg_set"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical" /></ScrollView>
★ 引用文字资源并设置对应Item属性
public class MainActivity2 extends LouActivity {private Activity mContext;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_setting);mContext = this;initView();}private void initView() {SettingLayout.IClickListener listener = new SettingLayout.IClickListener() {@Overridepublic void click(SettingLayout layout, SettingLayout.Item item) {switch (item.titleStrId) {case R.string.app_name_0:ChangeNameActivity.startActivity(mContext, layout, item);break;case R.string.app_name_1:item.contentStr = "双卡";break;case R.string.app_name_2:item.contentStr = "关闭";break;case R.string.app_name_3:item.contentStr = "已开启";break;case R.string.app_name_8:item.contentStr = "静音";break;}layout.refreshItem(item);Utoast.show(mContext, "点击了:" + mContext.getString(item.titleStrId));}};SettingLayout.Item item_0 = new SettingLayout.Item(R.string.app_name_0, R.mipmap.ic_launcher, "楼", null, true, SettingLayout.SEP.AFTERICON, listener);SettingLayout.Item item_0_1 = new SettingLayout.Item(R.string.app_name_0_1, R.mipmap.ic_launcher, "177", "CM", true, SettingLayout.SEP.AFTERICON, listener);SettingLayout.Item item_0_2 = new SettingLayout.Item(R.string.app_name_0_2, R.mipmap.ic_launcher, "60", "KG", true, SettingLayout.SEP.NO, listener);SettingLayout.Item item_1 = new SettingLayout.Item(R.string.app_name_1, R.mipmap.ic_launcher, null, null, true, SettingLayout.SEP.AFTERICON, listener);SettingLayout.Item item_2 = new SettingLayout.Item(R.string.app_name_2, R.mipmap.ic_launcher, null, null, true, SettingLayout.SEP.AFTERICON, listener);SettingLayout.Item item_3 = new SettingLayout.Item(R.string.app_name_3, R.mipmap.ic_launcher, null, null, true, SettingLayout.SEP.AFTERICON, listener);SettingLayout.Item item_4 = new SettingLayout.Item(R.string.app_name_4, R.mipmap.ic_launcher, null, null, true, SettingLayout.SEP.NO, listener);SettingLayout.Item item_5 = new SettingLayout.Item(R.string.app_name_5, R.mipmap.ic_launcher, null, null, true, SettingLayout.SEP.AFTERICON, listener);SettingLayout.Item item_6 = new SettingLayout.Item(R.string.app_name_6, R.mipmap.ic_launcher, null, null, true, SettingLayout.SEP.AFTERICON, listener);SettingLayout.Item item_7 = new SettingLayout.Item(R.string.app_name_7, R.mipmap.ic_launcher, null, null, true, SettingLayout.SEP.NO, listener);SettingLayout.Item item_8 = new SettingLayout.Item(R.string.app_name_8, 0, null, null, true, SettingLayout.SEP.FILL, listener);SettingLayout.Item item_9 = new SettingLayout.Item(R.string.app_name_9, 0, null, null, true, SettingLayout.SEP.FILL, listener);SettingLayout.Item item_10 = new SettingLayout.Item(R.string.app_name_10, 0, null, null, true, SettingLayout.SEP.NO, listener);SettingLayout.Item item_11 = new SettingLayout.Item(R.string.app_name_11, R.mipmap.ic_launcher, null, null, false, SettingLayout.SEP.NO, listener);SettingLayout.Item item_12 = new SettingLayout.Item(R.string.app_name_12, R.mipmap.ic_launcher, null, null, false, SettingLayout.SEP.FILL, listener);SettingLayout.Item item_13 = new SettingLayout.Item(R.string.app_name_13, R.mipmap.ic_launcher, null, null, false, SettingLayout.SEP.NO, listener);SettingLayout.Item item_14 = new SettingLayout.Item(R.string.app_name_14, R.mipmap.ic_launcher, null, null, false, SettingLayout.SEP.FILL, listener);SettingLayout.Item item_15 = new SettingLayout.Item(R.string.app_name_15, R.mipmap.ic_launcher, null, null, false, SettingLayout.SEP.NO, listener);SettingLayout s = (SettingLayout) findViewById(R.id.svg_set);s.addSpace(Uscreen.dp2Px(this, 12));s.addHeadTips("个人信息");s.addItem(item_0);s.addItem(item_0_1);s.addItem(item_0_2);s.addSpace(Uscreen.dp2Px(this, 12));s.addHeadTips("无线和网络");s.addItem(item_1);s.addItem(item_2);s.addItem(item_3);s.addItem(item_4);s.addSpace(Uscreen.dp2Px(this, 24));s.addHeadTips("提示和通知");s.addItem(item_5);s.addItem(item_6);s.addItem(item_7);s.addSpace(Uscreen.dp2Px(this, 12));s.addHeadTips("反馈");s.addItem(item_8);s.addItem(item_9);s.addItem(item_10);s.addSpace(Uscreen.dp2Px(this, 24));s.addHeadTips("微信");s.addItem(item_11);s.addSpace(Uscreen.dp2Px(this, 12));s.addItem(item_12);s.addItem(item_13);s.addSpace(Uscreen.dp2Px(this, 12));s.addItem(item_14);s.addItem(item_15);s.addSpace(Uscreen.dp2Px(this, 48));s.addSpace(Uscreen.dp2Px(this, 12));}}
通用源代码
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="48dp"android:background="#ffffff"android:paddingEnd="16dp"android:paddingStart="16dp" ><ImageViewandroid:id="@+id/iv_set_icon"android:layout_width="48dp"android:layout_height="48dp"android:layout_alignParentStart="true"android:layout_centerVertical="true"android:contentDescription="@string/app_name"android:padding="14dp"android:visibility="gone" /><TextViewandroid:id="@+id/tv_set_title"android:layout_width="wrap_content"android:layout_height="match_parent"android:layout_toEndOf="@+id/iv_set_icon"android:ellipsize="end"android:gravity="center_vertical"android:maxLines="1"android:text="标题"android:textSize="14sp" /><ImageViewandroid:id="@+id/iv_set_to_right"android:layout_width="14dp"android:layout_height="14dp"android:layout_alignParentEnd="true"android:layout_centerVertical="true"android:layout_marginStart="4dp"android:background="@mipmap/ic_go"android:visibility="gone" /><TextViewandroid:id="@+id/tv_set_unit"android:layout_width="wrap_content"android:layout_height="match_parent"android:layout_toStartOf="@id/iv_set_to_right"android:ellipsize="end"android:gravity="center_vertical"android:maxLines="1"android:text="单位"android:textSize="14sp"android:visibility="gone" /><TextViewandroid:id="@+id/tv_set_content"android:layout_width="wrap_content"android:layout_height="match_parent"android:layout_toStartOf="@id/tv_set_unit"android:ellipsize="end"android:gravity="center_vertical"android:maxLines="1"android:text="内容"android:textSize="14sp"android:visibility="gone" /><Viewandroid:id="@+id/v_set_divider"android:layout_width="match_parent"android:layout_height="0.1dp"android:layout_alignParentBottom="true"android:layout_alignParentEnd="true"android:background="#999999"android:visibility="gone" /></RelativeLayout>
package com.lyloou.android.view;import android.annotation.SuppressLint;import android.content.Context;import android.graphics.Color;import android.text.TextUtils;import android.util.AttributeSet;import android.util.SparseArray;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.Space;import android.widget.TextView;import com.lyloou.android.R;import com.lyloou.android.util.Uscreen;import com.lyloou.android.util.Uview;public class SettingLayout extends LinearLayout {private Context mContext;private SparseArray<View> mItemViews;public SettingLayout(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);mContext = context;mItemViews = new SparseArray<View>();}public SettingLayout(Context context, AttributeSet attrs) {this(context, attrs, 0);}public SettingLayout(Context context) {this(context, null);}public SettingLayout addItem(Item item) {// 对参数进行判断()if (item == null) {throw new IllegalArgumentException("item为空");}if (mItemViews.get(item.titleStrId) != null) {throw new IllegalArgumentException("此Item项已存在,请不要重复添加");}// 从布局中加载得到视图;@SuppressLint("InflateParams")View v = LayoutInflater.from(mContext).inflate(R.layout.item_setting_layout, null);addView(v, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, Uscreen.dp2Px(mContext, 48)));// 添加到SparseArray中,便于后期进行其他操作;mItemViews.put(item.titleStrId, v);refreshItem(item);return this;}public SettingLayout refreshItem(final Item item) {if (item == null) {throw new NullPointerException("Item为空");}View v = mItemViews.get(item.titleStrId);if (v == null) {throw new IllegalArgumentException("尚未添加此Item, 请先通过addItem方法添加");}ImageView ivIcon = (ImageView) v.findViewById(R.id.iv_set_icon);TextView tvTitle = (TextView) v.findViewById(R.id.tv_set_title);TextView tvContent = (TextView) v.findViewById(R.id.tv_set_content);TextView tvUnit = (TextView) v.findViewById(R.id.tv_set_unit);ImageView ivToRight = (ImageView) v.findViewById(R.id.iv_set_to_right);View vDivider = v.findViewById(R.id.v_set_divider);// 根据数据初始化视图if (item.iconResId != 0) {ivIcon.setVisibility(View.VISIBLE);ivIcon.setImageResource(item.iconResId);}tvTitle.setText(item.titleStrId);if (!TextUtils.isEmpty(item.contentStr)) {tvContent.setVisibility(View.VISIBLE);tvContent.setText(item.contentStr);}if (!TextUtils.isEmpty(item.unitStr)) {tvUnit.setVisibility(View.VISIBLE);tvUnit.setText(item.unitStr);}if (item.hasToRight) {ivToRight.setVisibility(View.VISIBLE);}if (item.sep == SEP.FILL) {vDivider.setVisibility(View.VISIBLE);} else if (item.sep == SEP.AFTERICON) {vDivider.setVisibility(View.VISIBLE);ViewGroup.MarginLayoutParams mp = ((ViewGroup.MarginLayoutParams) vDivider.getLayoutParams());mp.leftMargin = Uscreen.dp2Px(mContext, 48);}if (item.listener != null) {Uview.clickEffectByAlphaWithBg(new OnClickListener() {@Overridepublic void onClick(View v) {item.listener.click(SettingLayout.this, item);}}, v);}return this;}public SettingLayout addCustomView(View view) {addView(view);return this;}public SettingLayout addSpace(int spaceHeight) {Space space = new Space(mContext);space.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, spaceHeight));addView(space);return this;}public SettingLayout addHeadTips(int strId) {return addHeadTips(mContext.getResources().getString(strId));}public SettingLayout addHeadTips(String tips) {TextView tvTips = new TextView(mContext);LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT);params.leftMargin = Uscreen.dp2Px(mContext, 16);params.bottomMargin = Uscreen.dp2Px(mContext, 8);tvTips.setLayoutParams(params);tvTips.setText(tips);tvTips.setTextColor(Color.DKGRAY);tvTips.setTextSize(12);addView(tvTips);return this;}public interface IClickListener {void click(SettingLayout layout, Item item);}/*** NO 表示不显示底部分割线* FILL 表示占满整个底部的分割线* AFTERICON 表示紧随图像的分割线*/public static enum SEP {NO, FILL, AFTERICON;}public static class Item {public int titleStrId;public int iconResId;public String contentStr;public String unitStr;public boolean hasToRight;public SEP sep;public IClickListener listener;public Item(int titleStrId) {this.titleStrId = titleStrId;}/*** @param titleStrId 字符串ID,用来标识Item(不允许重复,且必须有效)* @param iconResId 最左边的Icon图标(当等于0时,不显示图标)* @param contentStr 内容字符串* @param unitStr 单位字符串(之所以没有和内容字符串合并,目的是更灵活地获取内容)* @param hasToRight 是否显示向右的图标* @param sep 分割线样式* @param listener 给Item添加点击事件*/public Item(int titleStrId, int iconResId, String contentStr, String unitStr, boolean hasToRight, SEP sep,IClickListener listener) {super();this.iconResId = iconResId;this.titleStrId = titleStrId;this.contentStr = contentStr;this.unitStr = unitStr;this.hasToRight = hasToRight;this.sep = sep;this.listener = listener;}}}
原文:http://blog.csdn.net/ly1414725328/article/details/51335430