在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>