在android客户端设置界面开发实例写过一个设置界面,但是不具有通用性,这里将使用一种方法来实现通用性样式。这里我们主要是通过TypedArray来实现自定义属性。
一、TypeArray的介绍
这里使用网上一个例子,介绍一下TypeArray的基本使用。
1.1、编写attrs.xml
在res/values文件下面定义一个attrs.xml文件,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyView">
<attr name="textColor" format="color" />
<attr name="textSize" format="dimension" />
</declare-styleable>
</resources>
1.2 封装组件
我们在Java代码编写如下,其中下面的构造方法是重点,我们获取定义的属性R.styleable.MyView_textColor,获取方法中后面通常设定默认值(float textSize = a.getDimension(R.styleable.MyView_textSize, 36 );),防止我们在xml文件中没有定义,从而使用默认值!
MyView 就是定义在<declare-styleable name="MyView "></declare-styleable> 里的 名字,获取里面属性用 名字_ 属性 连接起来就可以.TypedArray 通常最后调用 .recycle() 方法,为了保持以后使用该属性一致性!
public MyView(Context context,AttributeSet attrs)
{
super(context,attrs);
mPaint = new Paint();
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyView);
int textColor = a.getColor(R.styleable.MyView_textColor,0XFFFFFFFF);
float textSize = a.getDimension(R.styleable.MyView_textSize, 36);
mPaint.setTextSize(textSize);
mPaint.setColor(textColor);
a.recycle();
}
1.3自定义组件添加到布局中
接下来就是将自定义的MyView加入布局中,并且使用自定义属性,自定义属性必须加上:
" xmlns:test ="http://schemas.android.com/apk/res/com.android.tutor" ,test是自定义属性的前缀,com.android.tutor 是我们包名
形式如下:
形式如下:
<com.android.tutor.MyView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
test:textSize="20px"
test:textColor="#fff"
/>
二、自定义布局设计
我们可以想象一下设置界面圆角分的情况,第一种就是一个圆角,第二种多个组成的头部,第三种就是多个组成的中部,第四种就是多个组成的下部。所以我们要设计四种布局,来进行匹配。
2.1、一个圆角布局的设计
首先设计圆角布局我们也要分为a:设计圆角b:设计布局
2.1.1圆角设计
<?xml version="1.0" encoding="utf-8"?>
<inset
xmlns:android="http://schemas.android.com/apk/res/android"
android:insetLeft="1.0px"
android:insetRight="1.0px"
android:insetTop="0.0px"
android:insetBottom="1.0px"
>
<selector>
<item android:state_pressed="true">
<shape>
<gradient
android:startColor="@color/bg_start_color_pressed"
android:endColor="@color/bg_start_color_pressed"
/>
<corners android:radius="10.0dip" />
</shape>
</item>
<item>
<shape>
<stroke
android:width="1.0px"
android:color="@color/rounded_container_border" />
<gradient
android:startColor="@color/bg_start_color_default"
android:endColor="@color/bg_start_color_default"
/>
<corners android:radius="10.0dip" />
</shape>
</item>
</selector>
</inset>
2.1.2 style设计
<style name="item_single">
<item name="android:clickable">true</item>
<item name="android:paddingTop">10dip</item>
<item name="android:paddingBottom">10dip</item>
<item name="android:paddingLeft">10dip</item>
<item name="android:paddingRight">10dip</item>
<item name="android:gravity">center_vertical</item>
<item name="android:background">@drawable/bg_view_rounded_single</item>
</style>
2.1.3 item布局设计
<?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="wrap_content"
android:minHeight="60dip"
style="@style/item_single"
>
<ImageView
android:id="@+id/item_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="center"
android:layout_centerVertical="true"
android:src="@drawable/widget_progress_medium_rotation_image"
android:contentDescription="@string/app_name"
/>
<ImageView
android:id="@+id/arrow_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/arrow_right"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="10dip"
android:contentDescription="@string/app_name"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/item_icon"
android:layout_toLeftOf="@id/arrow_right"
android:orientation="vertical"
android:gravity="center_vertical"
android:layout_centerVertical="true"
android:layout_marginLeft="10dip"
>
<TextView
android:id="@+id/item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="title"
android:textSize="16sp"
/>
<TextView
android:id="@+id/item_subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="subtitle"
/>
</LinearLayout>
</RelativeLayout>
2.1.4 显示效果
为了通用性,所以对于特定的调整没有放在item布局上面,对于LIstview的item,间距设置在listview上面,参数如下:
<ListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/title"
android:cacheColorHint="#00000000"
android:layout_marginLeft="5dip"
android:layout_marginRight="5dip"
android:layout_marginTop="5dip"
android:divider="@null"
android:dividerHeight="5dip"
android:fadeScrollbars="false"
android:fastScrollEnabled="false"
android:focusable="true"
android:focusableInTouchMode="true"
android:scrollbars="none"
android:scrollingCache="false"
></ListView>
2.2多个组成圆角
其实多个部分组成的圆角与一个圆角差不多,就是2.1.1圆角设计要改变一下,其他的都一样。
2.2.1 top圆角设计
<?xml version="1.0" encoding="utf-8"?>
<inset
xmlns:android="http://schemas.android.com/apk/res/android"
android:insetLeft="1.0px"
android:insetRight="1.0px"
android:insetTop="1.0px"
android:insetBottom="0.0px"
>
<selector>
<item android:state_pressed="true">
<shape>
<gradient
android:startColor="@color/bg_start_color_pressed"
android:endColor="@color/bg_start_color_pressed"
/>
<corners
android:topLeftRadius="10.0dip"
android:topRightRadius="10.0dip"
android:bottomLeftRadius="0.0dip"
android:bottomRightRadius="0.0dip" />
</shape>
</item>
<item>
<shape>
<stroke
android:width="1.0px"
android:color="@color/rounded_container_border" />
<gradient
android:startColor="@color/bg_start_color_default"
android:endColor="@color/bg_start_color_default"
/>
<corners
android:topLeftRadius="10.0dip"
android:topRightRadius="10.0dip"
android:bottomLeftRadius="0.0dip"
android:bottomRightRadius="0.0dip" />
</shape>
</item>
</selector>
</inset>
Style:
<style name="item_top"> <item name="android:clickable">true</item> <item name="android:focusable">true</item> <item name="android:paddingTop">10dip</item> <item name="android:paddingBottom">10dip</item> <item name="android:paddingLeft">10dip</item> <item name="android:paddingRight">10dip</item> <item name="android:gravity">center_vertical</item> <item name="android:background">@drawable/bg_view_rounded_top</item> </style>
xml:
<?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="wrap_content" android:minHeight="60dip" style="@style/item_top" > <ImageView android:id="@+id/item_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="center" android:layout_centerVertical="true" android:src="@drawable/widget_progress_medium_rotation_image" android:contentDescription="@string/app_name" /> <ImageView android:id="@+id/arrow_right" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/arrow_right" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight="10dip" android:contentDescription="@string/app_name" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_toRightOf="@id/item_icon" android:layout_toLeftOf="@id/arrow_right" android:orientation="vertical" android:gravity="center_vertical" android:layout_centerVertical="true" android:layout_marginLeft="10dip" > <TextView android:id="@+id/item_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="title" android:textSize="16sp" /> <TextView android:id="@+id/item_subtitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="subtitle" /> </LinearLayout> </RelativeLayout>
2.2.2 bottom圆角设计
<?xml version="1.0" encoding="utf-8"?> <inset xmlns:android="http://schemas.android.com/apk/res/android" android:insetLeft="1.0px" android:insetRight="1.0px" android:insetTop="0.0px" android:insetBottom="1.0px" > <selector> <item android:state_pressed="true"> <shape> <gradient android:startColor="@color/bg_start_color_pressed" android:endColor="@color/bg_start_color_pressed" /> <corners android:topLeftRadius="0.0dip" android:topRightRadius="0.0dip" android:bottomLeftRadius="10.0dip" android:bottomRightRadius="10.0dip" /> </shape> </item> <item> <shape> <stroke android:width="1.0px" android:color="@color/rounded_container_border" /> <gradient android:startColor="@color/bg_start_color_default" android:endColor="@color/bg_start_color_default" /> <corners android:topLeftRadius="0.0dip" android:topRightRadius="0.0dip" android:bottomLeftRadius="10.0dip" android:bottomRightRadius="10.0dip" /> </shape> </item> </selector> </inset>
<style name="item_bottom"> <item name="android:clickable">true</item> <item name="android:paddingTop">10dip</item> <item name="android:paddingBottom">10dip</item> <item name="android:paddingLeft">10dip</item> <item name="android:paddingRight">10dip</item> <item name="android:gravity">center_vertical</item> <item name="android:background">@drawable/bg_view_rounded_bottom</item> </style>
2.2.3 middle圆角设计
<?xml version="1.0" encoding="utf-8"?> <inset xmlns:android="http://schemas.android.com/apk/res/android" android:insetLeft="1.0px" android:insetRight="1.0px" android:insetTop="0.0px" android:insetBottom="0.0px" > <selector> <item android:state_pressed="true"> <shape> <gradient android:startColor="@color/bg_start_color_pressed" android:endColor="@color/bg_start_color_pressed" /> <corners android:radius="0.0dip" /> </shape> </item> <item> <shape> <stroke android:width="1.0px" android:color="@color/rounded_container_border" /> <gradient android:startColor="@color/bg_start_color_default" android:endColor="@color/bg_start_color_default" /> <corners android:radius="0.0dip" /> </shape> </item> </selector> </inset>
<style name="item_middle"> <item name="android:clickable">true</item> <item name="android:paddingTop">10dip</item> <item name="android:paddingBottom">10dip</item> <item name="android:paddingLeft">10dip</item> <item name="android:paddingRight">10dip</item> <item name="android:gravity">center_vertical</item> <item name="android:background">@drawable/bg_view_rounded_middle</item> </style>
2.2.4父布局的圆角
<?xml version="1.0" encoding="UTF-8"?> <inset xmlns:android="http://schemas.android.com/apk/res/android" android:insetLeft="1.0px" android:insetRight="1.0px" android:insetTop="1.0px" android:insetBottom="1.0px" > <shape> <stroke android:width="1.0px" android:color="@color/rounded_container_border" /> <solid android:color="@color/rounded_container_border" /> <corners android:radius="10.0dip" /> </shape> </inset>
2.3 圆角组件封装
package com.jwzhangjie.smarttv_client.widget; import com.jwzhangjie.smarttv_client.R; import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; public class RoundItem extends RelativeLayout{ private LayoutInflater mInflater; private RelativeLayout mContainer; private ClickListener mClickListener; private int mLayoutId; private ImageView leftImageView; private TextView titleTextView; private TextView subtitleTextView; private TextView valueTextView; private ImageView rightImageView; private CharSequence mTitle; private CharSequence mSubtitle; private CharSequence mValue; private boolean clickable; private int mImage; public RoundItem(Context context, AttributeSet attrs) { super(context, attrs); mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundItem, 0, 0); int mLayoutValue = a.getInteger(R.styleable.RoundItem_layout, R.layout.item_rounded_single); switch (mLayoutValue) { case 0: mLayoutId = R.layout.item_rounded_top; break; case 1: mLayoutId = R.layout.item_rounded_middle; break; case 2: mLayoutId = R.layout.item_rounded_bottom; break; default: mLayoutId = R.layout.item_rounded_single; } mTitle = a.getString(R.styleable.RoundItem_title); mSubtitle = a.getString(R.styleable.RoundItem_subtitle); mValue = a.getString(R.styleable.RoundItem_value); mImage = a.getResourceId(R.styleable.RoundItem_image, -1); clickable = a.getBoolean(R.styleable.RoundItem_clickable, true); // 根据layout获取view mContainer = (RelativeLayout) mInflater.inflate(mLayoutId, null); // 初始化view中各个item leftImageView = (ImageView) mContainer.findViewById(R.id.item_icon); titleTextView = (TextView) mContainer.findViewById(R.id.item_title); subtitleTextView = (TextView) mContainer.findViewById(R.id.item_subtitle); valueTextView = (TextView) mContainer.findViewById(R.id.item_value); rightImageView = (ImageView) mContainer.findViewById(R.id.arrow_right); LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); // 初始化值 if(mTitle != null) { titleTextView.setText(mTitle.toString()); } else { titleTextView.setText("subtitle"); } if(mSubtitle != null) { subtitleTextView.setText(mSubtitle.toString()); } else { subtitleTextView.setVisibility(View.GONE); } if(mValue != null) { valueTextView.setText(mValue.toString()); } else { valueTextView.setVisibility(View.GONE); } if(mImage > -1) { leftImageView.setImageResource(mImage); } if(clickable) { mContainer.setOnClickListener( new OnClickListener() { @Override public void onClick(View view) { if(mClickListener != null) mClickListener.onClick(RoundItem.this); } }); }else { mContainer.setClickable(false); } addView(mContainer, params); a.recycle(); } public interface ClickListener { void onClick(View view); } /** * * @param listener */ public void addClickListener(ClickListener listener) { this.mClickListener = listener; } public void setTitle(String title) { if(title != null) { titleTextView.setText(title); } else { titleTextView.setText("subtitle"); } } public void setSubtitle(String subTitle) { if(subTitle != null) { subtitleTextView.setText(subTitle); } else { subtitleTextView.setVisibility(View.GONE); } } public void setImage(int image) { if(image > -1) { leftImageView.setImageResource(image); } } public void setArrow(boolean visiable){ if (visiable) { rightImageView.setVisibility(View.VISIBLE); }else { rightImageView.setVisibility(View.INVISIBLE); } } public void setValue(String value) { if(value != null) { if(valueTextView.getVisibility() != View.VISIBLE) valueTextView.setVisibility(View.VISIBLE); valueTextView.setText(value); } else { valueTextView.setVisibility(View.GONE); } } public String getValue() { return valueTextView.getText().toString(); } public String getTitle() { return titleTextView.getText().toString(); } }
2.4 圆角组件的应用--设置界面设计
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:round="http://schemas.android.com/apk/res/com.jwzhangjie.smarttv_client" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <com.jwzhangjie.smarttv_client.widget.RoundItem android:layout_width="match_parent" android:layout_height="60dip" android:layout_marginTop="10dip" android:layout_marginLeft="10dip" android:layout_marginRight="10dip" round:title="title" round:subtitle="subtitle" round:value="value" round:image="@drawable/widget_progress_medium_rotation_image" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dip" android:layout_marginLeft="10dip" android:layout_marginRight="10dip" android:orientation="vertical" android:background="@drawable/bg_view_rounded_container" > <com.jwzhangjie.smarttv_client.widget.RoundItem android:layout_width="match_parent" android:layout_height="60dip" round:title="title" round:subtitle="subtitle" round:value="value" round:image="@drawable/widget_progress_medium_rotation_image" round:layout="0" /> <com.jwzhangjie.smarttv_client.widget.RoundItem android:layout_width="match_parent" android:layout_height="60dip" round:title="title" round:subtitle="subtitle" round:value="value" round:image="@drawable/widget_progress_medium_rotation_image" round:layout="1" /> <com.jwzhangjie.smarttv_client.widget.RoundItem android:layout_width="match_parent" android:layout_height="60dip" round:title="title" round:subtitle="subtitle" round:value="value" round:image="@drawable/widget_progress_medium_rotation_image" round:layout="1" /> <com.jwzhangjie.smarttv_client.widget.RoundItem android:layout_width="match_parent" android:layout_height="60dip" round:title="title" round:subtitle="subtitle" round:value="value" round:image="@drawable/widget_progress_medium_rotation_image" round:layout="2" /> </LinearLayout> </LinearLayout>