当前位置: 代码迷 >> Android >> 关于界面
  详细解决方案

关于界面

热度:22   发布时间:2016-04-28 00:13:58.0
上门洗车APP --- Android客户端开发 之 项目结构介绍
上门洗车APP --- Android客户端开发 之 项目结构介绍


前言

虽然公司项目较紧,但还是抽出时间给大家继续更新。     o_O"~ 感谢大家的关注,很高兴和大家共同学习。前面给大家分享了项目中的以下内容:

上门洗车APP --- Android客户端开发 前言及业务简介

上门洗车APP --- Android客户端开发 之 网络框架封装介绍(一)

上门洗车APP --- Android客户端开发 之 网络框架封装介绍(二)



之前有很多朋友私信过来说想打包一份源码学习,由于本项目也是还在开发中,进度不是很快,后台那边的一系列接口需要调试,自己也是时间精力有限,还请朋友见谅。本篇博文给大家介绍项目的  整体目录结构界面开发、项目中所使用的  自定义控件技术点 等,同时也会打包一份目前最新的源码供感兴趣的朋友学习。


关于项目目录结构

首先我们来看下项目的目录结构,给大家做一些简单的介绍:


                  


由于目录过多,我们分了两张图展示,先对源码包的管理进行介绍:

org.gaochun.activity  -------> 管理Activity

org.gaochun.adapter -------> 通用万能Adapter

org.gaochun.android.http  -------> Android-Async-Http框架

org.gaochun.android.http.manager  -------> 通用数据管理(常量、URL、网络请求 等)

org.gaochun.android.http.network -------> 自定义回调接口

org.gaochun.android.http.request -------> 请求参数管理

org.gaochun.model -------> 实体Bean管理

org.gaochun.parser -------> 解析接口及抽象解析器管理

org.gaochun.parser.impl -------> 解析器管理

org.gaochun.receiver -------> 监听推送消息的Receiver

org.gaochun.ui -------> 标题栏及Application管理

org.gaochun.utils  -------> 常用工具类

org.gaochun.widget -------> 自定义控件管理(AlertDialog、圆形ImageView、带声音的Toast等)


部分技术点

有木有感觉层次还是比较清晰的呢?好了,不扯淡!给出了这些包中各自的职责后,相信朋友可以很清晰的找到对应所需要了解的类。这里大致介绍两个包中的内容,org.gaochun.adapter 和 org.gaochun.widget 其他包在之前介绍网络框架中大致有提到,看如下两个包中的内容:

            

一个是通用的Adapter和通用的ViewHolder缓存类,一个是自定义的提示框、圆形ImageView、带声音的Toast 。


有时候项目里面有好多好多ListView,记得以前一种傻逼的做法是往 adapter 包中塞各种 OrderAdapter,HistoryAdapter,...... 然后每个 adapter 都是 extends BaseAdapter,如果有一百个Adapter,我去,这他妈是个什么概念。。。。嘿嘿,后来学乖了哟。


CommonAdapter:

package org.gaochun.adapter;import java.util.List;import android.content.Context;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;/** * 通用 Adapter * @author gao_chun * * @param <T> */public abstract class CommonAdapter<T> extends BaseAdapter{    protected LayoutInflater mInflater;    protected Context mContext;    protected List<T> mDatas;    protected final int mItemLayoutId;    /**     * 初始化通用Adapter     * @param context   上下文     * @param mDatas    需要显示的数据集合     * @param itemLayoutId  子布局文件     */    public CommonAdapter(Context context, List<T> mDatas, int itemLayoutId)    {        this.mContext = context;        this.mInflater = LayoutInflater.from(mContext);        this.mDatas = mDatas;        this.mItemLayoutId = itemLayoutId;    }    @Override    public int getCount()    {        return mDatas.size();    }    @Override    public T getItem(int position)    {        return mDatas.get(position);    }    @Override    public long getItemId(int position)    {        return position;    }    @Override    public View getView(int position, View convertView, ViewGroup parent)    {        //从ViewHolder中获取控件view,若为空则创建        final ViewHolder viewHolder = getViewHolder(position, convertView,parent);        Log.i("gao_chun", position+"");        convert(viewHolder, getItem(position));        return viewHolder.getConvertView();    }    /**     * 抽取出getView中间改变的部分     * @param helper    holder缓存对象     * @param item      Bean对象     */    public abstract void convert(ViewHolder helper, T item);    /**     * 获得ViewHolder中的view     * @param position     * @param convertView     * @param parent     * @return     */    private ViewHolder getViewHolder(int position, View convertView,ViewGroup parent)    {        return ViewHolder.get(mContext, convertView, parent, mItemLayoutId,position);    }}

ViewHolder:

package org.gaochun.adapter;import android.content.Context;import android.graphics.Bitmap;import android.util.SparseArray;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.TextView;import com.nostra13.universalimageloader.core.ImageLoader;/** * 通用 ViewHolder 缓存类 * @author gao_chun * */public class ViewHolder{    private ImageLoader imageLoader = ImageLoader.getInstance();    private final SparseArray<View> mViews;    private int mPosition;    private View mConvertView;    private ViewHolder(Context context, ViewGroup parent, int layoutId,int position)    {        this.mPosition = position;        this.mViews = new SparseArray<View>();        mConvertView = LayoutInflater.from(context).inflate(layoutId, parent,false);        mConvertView.setTag(this);   // setTag    }    /**     * 拿到一个ViewHolder对象     *     * @param context     * @param convertView     * @param parent     * @param layoutId     * @param position     * @return     */    public static ViewHolder get(Context context, View convertView,ViewGroup parent, int layoutId, int position)    {        if (convertView == null){            //创建ViewHolder对象 ,并做View缓存            return new ViewHolder(context, parent, layoutId, position);        }        return (ViewHolder)convertView.getTag();    }    public View getConvertView()    {        return mConvertView;    }    /**     * 通过控件的Id获取对于的控件,如果没有则加入views     *     * @param viewId     * @return     */    public <T extends View> T getView(int viewId){        View view = mViews.get(viewId);        if (view == null){            view = mConvertView.findViewById(viewId);            mViews.put(viewId, view);        }        return (T)view;    }    /**     * 为TextView设置字符串     *     * @param viewId     * @param text     * @return     */    public ViewHolder setText(int viewId, String text)    {        TextView view = getView(viewId);        view.setText(text);        return this;    }    /**     * 为ImageView设置图片     *  setImageResource     * @param viewId     * @param drawableId     * @return     */    public ViewHolder setImageResource(int viewId, int drawableId)    {        ImageView view = getView(viewId);        view.setImageResource(drawableId);        return this;    }    /**     * 为ImageView设置图片     *  setImageBitmap     * @param viewId     * @param drawableId     * @return     */    public ViewHolder setImageBitmap(int viewId, Bitmap bm)    {        ImageView view = getView(viewId);        view.setImageBitmap(bm);        return this;    }    /**     * 为ImageView设置图片     *  setImageByUrl     * @param viewId     * @param drawableId     * @return     */   /* public ViewHolder setImageByUrl(int viewId, String url)    {        ImageLoader.getInstance(3, Type.LIFO).loadImage(url,(ImageView) getView(viewId));        return this;    }*/    public ViewHolder setImageByUrl(int viewId, String url){        imageLoader.displayImage(url,(ImageView)getView(viewId));        return this;    }    public int getPosition(){        return mPosition;    }}

这里还要给大家推荐一个技巧:ListView中按钮监听器 设置 及 优化,有个需要注意的地方是 setTag 可以记录信息。


下面是实现带声音的Toast控件类源码,大家可以下载源码了解学习:

package org.gaochun.widget;import com.washcar.R;import android.content.Context;import android.media.MediaPlayer;import android.util.DisplayMetrics;import android.view.LayoutInflater;import android.view.View;import android.widget.TextView;import android.widget.Toast;/** * 自定义声音提示 Toast控件 * @version 0.1 * @created gao_chun */public class SoundToast extends Toast{	private MediaPlayer mPlayer;	private boolean isSound;	public SoundToast(Context context){		this(context, false);	}	public SoundToast(Context context, boolean isSound){		super(context);		this.isSound = isSound;		mPlayer = MediaPlayer.create(context, R.raw.newdatatoast);		mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener(){			@Override			public void onCompletion(MediaPlayer mp){				mp.release();   //释放资源			}		});	}	@Override	public void show()	{		super.show();		if (isSound){			mPlayer.start();		}	}	/**	 * 获取控件实例	 *	 * @param context	 * @param text  提示消息	 * @param isSound   是否播放声音	 * @param duration  时长	 * @return	 */	public static SoundToast show(Context context, CharSequence text, boolean isSound, int duration){		SoundToast result = new SoundToast(context, isSound);		LayoutInflater inflate = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);		DisplayMetrics dm = context.getResources().getDisplayMetrics();		View v = inflate.inflate(R.layout.layout_toast, null);	//加载Toast布局		v.setMinimumWidth(dm.widthPixels);  //设置控件最小宽度为手机屏幕宽度		TextView tv = (TextView) v.findViewById(R.id.tv_lable);		tv.setText(text);		result.setView(v);		result.setDuration(duration);// 设置 显示多长时间;		//result.setGravity(Gravity.CENTER,0,0);		return result;	}}

注:语音提示播报功能已经实现,在接收到服务器推送的订单后自动播报。由于目前方便测试,在首页点击 订单中 按钮便可看到效果。部分自定义控件这里也不过多的介绍了,感兴趣的童鞋可以下载了研究研究,没准以后在自己项目中就用到了。关于语音播报,在讯飞平台注册了ID,之前简单介绍过一些用法:Android语音播报、后台播报、语音识别 ,大家可以参考下。


关于界面

关于res目录下的界面,想了想,貌似也没有什么好说的了,只需要掌握一些常用的布局技巧,熟练使用Android中的布局属性,基本上简单的界面没有什么太大的问题。由于使用了 dimens 做适配,只需要将使用dp的地方,换成如:android:padding="@dimen/dimen_20_dip" 就可以了,如登录界面:



<?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="match_parent"    android:background="@color/background" >    <LinearLayout        android:id="@+id/layout_table"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_marginTop="@dimen/dimen_30_dip"        android:orientation="vertical" >        <include layout="@layout/layout_line_horizonal" />        <EditText            android:id="@+id/edit_username"            style="@style/text_16"            android:layout_width="match_parent"            android:layout_height="@dimen/dimen_75_dip"            android:background="@color/white"            android:hint="@string/text_hint_username"            android:inputType="phone"            android:maxLength="11"            android:padding="@dimen/dimen_20_dip"            android:textColorHint="@color/text_hint_color" />        <EditText            android:id="@+id/edit_password"            style="@style/text_16"            android:layout_width="match_parent"            android:layout_height="@dimen/dimen_75_dip"            android:layout_marginTop="@dimen/row_margin"            android:background="@color/white"            android:hint="@string/text_hint_password"            android:inputType="textPassword"            android:padding="@dimen/dimen_20_dip"            android:textColorHint="@color/text_hint_color" />        <include layout="@layout/layout_line_horizonal" />    </LinearLayout>    <Button        android:id="@+id/button_login"        style="@style/text_white_18"        android:layout_width="match_parent"        android:layout_height="@dimen/dimen_60_dip"        android:layout_below="@+id/layout_table"        android:layout_marginTop="@dimen/dimen_65_dip"        android:background="@drawable/button_selector"        android:gravity="center"        android:onClick="onClick"        android:text="@string/text_login" /></RelativeLayout>


个人中心界面:



<?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="match_parent"    android:background="@color/background" >    <RelativeLayout        android:id="@+id/layout_top"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:background="@color/white" >        <RelativeLayout            android:id="@+id/layout_table"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:background="@drawable/person_bg"            android:padding="@dimen/dimen_20_dip" >            <org.gaochun.widget.RoundImageView                android:id="@+id/iv_avatar"                android:layout_width="@dimen/dimen_135_dip"                android:layout_height="@dimen/dimen_135_dip"                android:layout_marginLeft="@dimen/dimen_20_dip"                android:layout_marginRight="@dimen/dimen_10_dip"                android:scaleType="centerCrop"                android:src="@drawable/gao_chun" />            <TextView                android:id="@+id/tv_user_name"                style="@style/text_white_16"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_marginLeft="@dimen/dimen_60_dip"                android:layout_marginTop="@dimen/dimen_30_dip"                android:layout_toRightOf="@+id/iv_avatar"                android:text="gao_chun"                android:textStyle="bold" />            <TextView                android:id="@+id/tv_user_money"                style="@style/text_white_16"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_below="@+id/tv_user_name"                android:layout_marginLeft="@dimen/dimen_45_dip"                android:layout_marginTop="@dimen/dimen_20_dip"                android:layout_toRightOf="@+id/iv_avatar"                android:text="余额:12345"                android:textStyle="bold" />        </RelativeLayout>        <LinearLayout            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_below="@+id/layout_table"            android:orientation="horizontal"            android:padding="@dimen/dimen_20_dip" >            <TextView                style="@style/text_16"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_marginLeft="@dimen/dimen_25_dip"                android:layout_weight="1"                android:text="优评:2" />            <View                android:layout_width="1px"                android:layout_height="match_parent"                android:layout_marginRight="@dimen/dimen_40_dip"                android:background="@color/line_gray" />            <TextView                style="@style/text_16"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_weight="1"                android:text="中评:4" />            <View                android:layout_width="1px"                android:layout_height="match_parent"                android:layout_marginRight="@dimen/dimen_40_dip"                android:background="@color/line_gray" />            <TextView                style="@style/text_16"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_weight="1"                android:text="差评:0" />        </LinearLayout>    </RelativeLayout>    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_below="@+id/layout_top"        android:layout_marginTop="@dimen/dimen_30_dip"        android:orientation="vertical" >        <View            android:layout_width="match_parent"            android:layout_height="1px"            android:background="@color/line_gray" />        <TextView            android:id="@+id/tv_my_order"            style="@style/text_black_16"            android:layout_width="match_parent"            android:layout_height="@dimen/dimen_75_dip"            android:background="@drawable/row_selector"            android:clickable="true"            android:drawableLeft="@drawable/person_order"            android:drawablePadding="@dimen/dimen_40_dip"            android:gravity="center_vertical"            android:onClick="onClick"            android:padding="@dimen/dimen_25_dip"            android:text="@string/text_my_order" />        <TextView            android:id="@+id/tv_my_vip"            style="@style/text_black_16"            android:layout_width="match_parent"            android:layout_height="@dimen/dimen_75_dip"            android:layout_marginTop="@dimen/row_margin"            android:background="@drawable/row_selector"            android:clickable="true"            android:drawableLeft="@drawable/person_vip"            android:drawablePadding="@dimen/dimen_40_dip"            android:gravity="center_vertical"            android:onClick="onClick"            android:padding="@dimen/dimen_25_dip"            android:text="@string/text_my_vip" />        <TextView            android:id="@+id/tv_my_notify"            style="@style/text_black_16"            android:layout_width="match_parent"            android:layout_height="@dimen/dimen_75_dip"            android:layout_marginTop="@dimen/row_margin"            android:background="@drawable/row_selector"            android:clickable="true"            android:drawableLeft="@drawable/person_inform"            android:drawablePadding="@dimen/dimen_40_dip"            android:gravity="center_vertical"            android:onClick="onClick"            android:padding="@dimen/dimen_25_dip"            android:text="@string/text_my_information" />        <TextView            android:id="@+id/tv_my_more"            style="@style/text_black_16"            android:layout_width="match_parent"            android:layout_height="@dimen/dimen_75_dip"            android:layout_marginTop="@dimen/row_margin"            android:background="@drawable/row_selector"            android:clickable="true"            android:drawableLeft="@drawable/person_more"            android:drawablePadding="@dimen/dimen_40_dip"            android:gravity="center_vertical"            android:onClick="onClick"            android:padding="@dimen/dimen_25_dip"            android:text="@string/text_more" />        <include layout="@layout/layout_line_horizonal" />    </LinearLayout>    <Button        android:id="@+id/button_submit"        style="@style/text_white_18"        android:layout_width="match_parent"        android:layout_height="@dimen/dimen_65_dip"        android:layout_alignParentBottom="true"        android:layout_marginBottom="@dimen/dimen_40_dip"        android:background="@drawable/button_selector"        android:gravity="center"        android:onClick="onClick"        android:text="@string/text_exit" /></RelativeLayout>

关于服务器端订单推送及其他技术点,日后总结了看有没有必要给大家再介绍下,先就到这里吧!


源码下载:http://download.csdn.net/download/gao_chun/8861137


@remark: 本系列Blog禁止转载


版权声明:本文为博主原创文章,未经博主允许不得转载。

  相关解决方案