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);
    }

}