Android开发编码规范之常用控件布局(三)
一、TextView布局要求:需要设置大约10个属性。
UI标注和交互注意事项: 1.文字大小 2.文字的颜色 3.文字的内外边距 4.是否单行显示
编码重点注意事项 : 1.文字大小 2.文字的颜色 3.文字的内外边距 4.是否单行显示
1.1、TextView一般需要设置10个属性
1.长度和宽度设置
1.设置id
2.设置文本颜色
3.设置文本大小
4.设置内间距
5.设置外间距
6.设置文本框在父布局中的位置
7.设置文本子布局中的位置
8.行数限制(不限制行数可以去掉)
9.设置内容(可选)
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tv_remark"
android:textColor="@color/black_text"
android:textSize="13sp"
android:padding="5dp"
android:layout_margin="5dp"
android:layout_gravity="center"
android:gravity="center_vertical"
android:maxLines="1"
android:ellipsize="end"
android:text="sssss"
/>
其他需要注意的地方
1.设置字体
android:textStyle=”bold”
2.行间距
android:lineSpacingExtra=”5dp”
1.2、添加style时 需要设置颜色 字体大小 内外边距等属性。
<!--TextView 单行默认-->
<style name="text_single_default">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:maxLines">1</item>
<item name="android:ellipsize">end</item>
<item name="android:gravity">center_vertical</item>
<item name="android:layout_gravity">center</item>
</style>
<!--TextView 不限制行数默认-->
<style name="text_more_default">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:gravity">center_vertical</item>
<item name="android:layout_gravity">center</item>
</style>
<TextView
style="@style/text_single_default"
android:id="@+id/tv_remark1"
android:textColor="@color/black_text"
android:textSize="13sp"
android:padding="5dp"
android:layout_margin="5dp"
android:text="sssss"
/>
二、EditText布局要求:需要设置大约15个属性。
UI标注和交互注意事项: 1.文字大小 2.文字的颜色 3.文字的内外边距 4.是否单行显示 5.文本长度限制 6.输入类型限制
编码重点注意事项 : 1.文字大小 2.文字的颜色 3.文字的内外边距 4.是否单行显示 5.文本长度限制 6.输入类型限制
2.1EditText一般需要设置15个属性
1.输入框长度和宽度
2.输入框ID
3.输入框字体颜色
4.输入框字体大小
5.内边距
6.外边距
7.控件相对父控件位置
8.文字位置
9.软键盘默认属性(下一个 、完成、发送搜索)
10.限制文本的行数
11.限制文本的输入字符长度
12.输入框输入内容类型
13.默认置灰输入内容
14.输入框背景框
15.自定义鼠标
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/et_context"
android:textColor="@color/black_text"
android:textSize="15sp"
android:padding="6dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="15dp"
android:layout_gravity="center"
android:gravity="center_vertical"
android:imeOptions="actionDone"
android:maxLines="1"
android:ellipsize="end"
android:maxLength="200"
android:inputType="text"
android:hint="请输入内容"
android:background="@drawable/shape_dialog_edit_bg"
android:textCursorDrawable="@drawable/shape_input_cursor"
/>
2.2设置style之后,需要考虑 字体颜色 、大小、内外边距、长度、输入内容限制
<!--EditText 单行显示-->
<style name="edit_single_default">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:gravity">center_vertical</item>
<item name="android:layout_gravity">center</item>
<item name="android:imeOptions">actionDone</item>
<item name="android:inputType">text</item>
<item name="android:background">@drawable/shape_dialog_edit_bg</item>
<item name="android:textCursorDrawable">@drawable/shape_input_cursor</item>
<item name="android:maxLines">1</item>
<item name="android:ellipsize">end</item>
</style>
<EditText
style="@style/edit_single_default"
android:id="@+id/et_context1"
android:textColor="@color/black_text"
android:textSize="15sp"
android:padding="6dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="15dp"
android:maxLength="200"
android:hint="请输入内容"
/>
Edit鼠标图片
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners
android:radius="1dp"
/>
<size android:width="1dp"
/>
<solid
android:color="@color/black_text"
/>
<stroke
android:width="0dp"
android:color="#FFFFFFFF"
/>
</shape>
Edit背景图片
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:dither="true"
android:shape="rectangle">
<corners android:radius="3dp" />
<stroke
android:width="0.5dp"
android:color="@color/grey_text" />
</shape>
三、ImageView布局要求:需要设置大约15个属性。
注意事项: 1.不要添加背景图片,而是需要采用src进行图片设置。 2.图片缩放类型根据情况考虑 3.设置图片内边距,扩大点击热点
1.设置控件的长度和宽度
2.设置图片
3.设置ID
4.设置缩放属性
5.设置内边距
6.设置外边距
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@drawable/bt_pause"
android:id="@+id/iv_play"
android:scaleType="centerInside"
android:paddingTop="17dp"
android:paddingBottom="17dp"
android:paddingLeft="13dp"
android:paddingRight="8dp"
/>
四.Button点击效果
采用和Textview类似的style ,设置点击事件的时候可以加上水波纹适配ripple_again_study_bg.xml
drawable文件夹下面添加ripple_again_study_bg.xml文件
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.android.com/apk/res/android"
android:color="@color/white_smoke_medium">
<item android:state_pressed="false">
<shape android:shape="rectangle">
<solid android:color="@color/white_smoke_light" />
<corners android:radius="0dp" />
</shape>
</item>
<item android:state_pressed="true">
<shape android:shape="rectangle">
<solid android:color="@color/gray_light" />
<corners android:radius="0dp" />
</shape>
</item>
</selector>
drawable-v21文件夹下面添加ripple_again_study_bg.xml文件
<?xml version="1.0" encoding="utf-8"?>
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/gray_light"
android:radius="0dp"
>
<item>
<shape
android:shape="rectangle">
<solid android:color="@color/white_smoke_light" />
</shape>
</item>
</ripple>
五.RecyclerView列表布局
mAdapter = new AnalysisAdapter(this,mLists);
rvAnalysis.setLayoutManager(new LinearLayoutManager(this));
rvAnalysis.setAdapter(mAdapter);
5.1、整个列表只有一种布局
package com.eaglesoul.eplatform.english.ui.adapter;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
import android.widget.TextView;
import com.eaglesoul.eplatform.english.R;
import com.eaglesoul.eplatform.english.ui.item.AnalysisItem;
import java.util.List;
/**
* description: 分析界面适配
* User: shaobing
* Date: 2016-06-07
* Time: 18:35
*/
public class AnalysisAdapter extends RecyclerView.Adapter<AnalysisAdapter.ViewHolder>{
private Context mContext;
private List<AnalysisItem> mLists;
private OnItemClickListener mListener;
/**
* 设置onItemClick监听
* @param mListener listener
*/
public void setOnItemClickListener(OnItemClickListener mListener) {
this.mListener = mListener;
}
public AnalysisAdapter(Context mContext, List<AnalysisItem> mLists) {
this.mLists = mLists;
this.mContext = mContext;
}
/**
* 更新数据
* update data
* @param mLists datas
*/
public void setData(List<AnalysisItem> mLists) {
this.mLists = mLists;
notifyDataSetChanged();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView mSee;
public TextView mTitle;
public TextView mNumber;
public ViewHolder(View view){
super(view);
mSee= (TextView) view.findViewById(R.id.btn_see);
mTitle = (TextView) view.findViewById(R.id.tv_title);
mNumber= (TextView) view.findViewById(R.id.tv_number);
}
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_analysis,viewGroup,false);
ViewHolder vh = new ViewHolder(view);
return vh;
}
//将数据与界面进行绑定的操作
@Override
public void onBindViewHolder(final ViewHolder viewHolder, int position) {
viewHolder.mTitle.setText(mLists.get(position).getTitle());
viewHolder.mNumber.setText(mLists.get(position).getNumber());
if(mLists.get(position).isClick()) {
viewHolder.mSee.setTextColor(mContext.getResources().getColor(R.color.black_gray));
}
else {
viewHolder.mSee.setTextColor(mContext.getResources().getColor(R.color.gray));
}
// set the listener OnItemClickListener
if(mListener != null) {
if(!viewHolder.itemView.hasOnClickListeners()) {
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int pos = viewHolder.getPosition();
mListener.onItemClick(viewHolder.mSee, pos);
}
});
}
}
viewHolder.itemView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
viewHolder.itemView.startAnimation(AnimationUtils.loadAnimation(mContext,R.anim.ainim_anlysis_click_down));
break;
}
case MotionEvent.ACTION_UP: {
viewHolder.itemView.startAnimation(AnimationUtils.loadAnimation(mContext,R.anim.ainim_anlysis_click_up));
break;
}
case MotionEvent.ACTION_CANCEL: {
viewHolder.itemView.startAnimation(AnimationUtils.loadAnimation(mContext,R.anim.ainim_anlysis_click_up));
break;
}
}
return false;
}
});
}
//获取数据的数量
@Override
public int getItemCount() {
if(mLists ==null) {
return 0;
}
return mLists.size();
}
/**
* description: 设置item点击监听
* User: shaobing
* Date: 2016/6/12
* Time: 17:08
*/
public interface OnItemClickListener {
void onItemClick(View view, int position);
}
}
5.1、整个列表只有两种布局
package com.eaglesoul.eplatform.english.ui.adapter;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.TextView;
import com.eaglesoul.eplatform.english.R;
import com.eaglesoul.eplatform.english.ui.item.WordItem;
import com.eaglesoul.eplatform.english.ui.widget.VoiceImageView;
import java.util.List;
/**
* description: 错误分析界面列表的适配器
* User: shaobing
* Date: 2016-06-07
* Time: 18:35
*/
public class HistoryAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
private Context mContext;
private List<WordItem> mLists;
//错误单词ID列表
private List<Integer> mErrorLists;
//错误单词数量列表
private List<Integer> mErrorNumbers;
private OnItemClickListener mListener;
private boolean isEdit;
private int mExpanlePositon= -1;
//建立枚举 2个item 类型
public enum ITEM_TYPE {
ITEM1,
ITEM2
}
/**
* 设置onItemClick监听
* @param mListener listener
*/
public void setOnItemClickListener(OnItemClickListener mListener) {
this.mListener = mListener;
}
/**
* Description :
* author :shaobing 2362017447@qq.com
* created date : 2016/6/7 18:51
*/
public HistoryAdapter(Context mContext, List<WordItem> mLists,List<Integer> mErrorLists,List<Integer> mErrorNumbers) {
this.mLists = mLists;
this.mContext = mContext;
this.mErrorLists = mErrorLists;
this.mErrorNumbers = mErrorNumbers;
}
/**
* 设置展开选项的位置
* @param positon 设置展开选项的位置
*/
public void setExpanlePositon(int positon)
{
this.mExpanlePositon = positon;
}
/**
* 更新数据
* update data
* @param mLists datas
*/
public void setData(List<WordItem> mLists,List<Integer> mErrorLists,List<Integer> mErrorNumbers) {
this.mLists = mLists;
this.mErrorLists = mErrorLists;
this.mErrorNumbers = mErrorNumbers;
notifyDataSetChanged();
}
/**
* 设置进行选择选项
* @param isEdit 判断是否进行选择
*/
public void setIsedit(boolean isEdit)
{
this.isEdit = isEdit;
}
public static class ViewHolder1 extends RecyclerView.ViewHolder {
public CheckBox cbSelect;
public TextView tvWord;
public TextView tvError;
public ViewHolder1(View view){
super(view);
cbSelect= (CheckBox) view.findViewById(R.id.cb_select);
tvWord = (TextView) view.findViewById(R.id.tv_word);
tvError= (TextView) view.findViewById(R.id.tv_error);
}
}
public static class ViewHolder2 extends RecyclerView.ViewHolder {
public TextView tvWord;
public TextView tvError;
private VoiceImageView ivVoice;
private TextView tv_detail;
public ViewHolder2(View view){
super(view);
tvWord = (TextView) view.findViewById(R.id.tv_word);
tvError= (TextView) view.findViewById(R.id.tv_error);
ivVoice= (VoiceImageView) view.findViewById(R.id.iv_voice);
tv_detail= (TextView) view.findViewById(R.id.tv_detail);
}
}
/**
* 在这里进行类型设计
* @param position
* @return
*/
@Override
public int getItemViewType(int position) {
if(mExpanlePositon!=-1 && mExpanlePositon==position) {
return ITEM_TYPE.ITEM2.ordinal();
}
else {
return ITEM_TYPE.ITEM1.ordinal();
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
//加载Item View的时候根据不同TYPE加载不同的布局
if (viewType == ITEM_TYPE.ITEM1.ordinal()) {
return new ViewHolder1(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_history, viewGroup, false));
} else {
return new ViewHolder2(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_history_detail, viewGroup, false));
}
}
//将数据与界面进行绑定的操作
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder viewHolder, int position) {
if(viewHolder instanceof ViewHolder1)
{
((ViewHolder1)viewHolder).tvWord.setText(mLists.get(position).getWords());
//错误单词的数量根据当前单词是否错误判断
String message;
int index = mErrorLists.indexOf(mLists.get(position).getWordId());
if( index== -1){
message = String.format(mContext.getResources().getString(R.string.histoy_number),0);
}else {
message = String.format(mContext.getResources().getString(R.string.histoy_number),mErrorNumbers.get(index));
}
((ViewHolder1)viewHolder).tvError.setText(message);
if(isEdit) {
((ViewHolder1)viewHolder).cbSelect.setVisibility(View.VISIBLE);
}
else {
((ViewHolder1)viewHolder).cbSelect.setVisibility(View.GONE);
}
// set the listener OnItemClickListener
if(mListener != null) {
if(! viewHolder.itemView.hasOnClickListeners()) {
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int pos = viewHolder.getPosition();
mListener.onItemClick(v, pos);
}
});
}
}
if(mLists.get(position).isSelect()) {
((ViewHolder1) viewHolder).cbSelect.setChecked(true);
}
else {
((ViewHolder1) viewHolder).cbSelect.setChecked(false);
}
//点击选中单词
if(mListener != null) {
if(! ((ViewHolder1) viewHolder).cbSelect.hasOnClickListeners()) {
((ViewHolder1) viewHolder).cbSelect.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int pos = viewHolder.getPosition();
mListener.onItemSelect(v, pos);
}
});
}
}
}
else if(viewHolder instanceof ViewHolder2) {
((ViewHolder2)viewHolder).tvWord.setText(mLists.get(position).getWords());
//错误单词的数量根据当前单词是否错误判断
String message;
int index = mErrorLists.indexOf(mLists.get(position).getWordId());
if( index== -1){
message = String.format(mContext.getResources().getString(R.string.histoy_number),0);
}else {
message = String.format(mContext.getResources().getString(R.string.histoy_number),mErrorNumbers.get(index));
}
((ViewHolder2)viewHolder).tvError.setText(message);
((ViewHolder2)viewHolder).tv_detail.setText(mLists.get(position).getWordNote());
//点击选中单词
if(mListener != null) {
if(! ((ViewHolder2)viewHolder).ivVoice.hasOnClickListeners()) {
((ViewHolder2)viewHolder).ivVoice.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int pos = viewHolder.getPosition();
mListener.onVoiceMessage(v,pos,mLists.get(pos).getWords());
}
});
}
}
//水波纹效果
if(mListener != null) {
if(! viewHolder.itemView.hasOnClickListeners()) {
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int pos = viewHolder.getPosition();
}
});
}
}
if(mLists.get(position).isVoice()) {
((ViewHolder2)viewHolder).ivVoice.startVoice(R.drawable.list_horn);
}
else {
((ViewHolder2)viewHolder).ivVoice.stopVoice(R.drawable.bt_horn);
}
}
else {
}
}
//获取数据的数量
@Override
public int getItemCount() {
if(mLists ==null) {
return 0;
}
return mLists.size();
}
/**
* description: 设置item点击监听
* User: shaobing(2362017447@qq.com)
* Date: 2016/6/12
* Time: 17:08
*/
public interface OnItemClickListener {
void onItemClick(View view, int position);
void onItemSelect(View view, int position);
void onVoiceMessage(View view, int position,String message);
}
}