上门洗车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,我去,这他妈是个什么概念。。。。嘿嘿,后来学乖了哟。
关于通用Adapter可参考:https://github.com/JoanZapata/base-adapter-helper
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;
-
-
-
-
-
-
- public abstract class CommonAdapter<T> extends BaseAdapter{
-
- protected LayoutInflater mInflater;
- protected Context mContext;
- protected List<T> mDatas;
- protected final int mItemLayoutId;
-
-
-
-
-
-
-
- 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)
- {
-
- final ViewHolder viewHolder = getViewHolder(position, convertView,parent);
-
- Log.i("gao_chun", position+"");
- convert(viewHolder, getItem(position));
-
- return viewHolder.getConvertView();
-
-
- }
-
-
-
-
-
-
- public abstract void convert(ViewHolder helper, T item);
-
-
-
-
-
-
-
-
-
- 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;
-
-
-
-
-
-
-
- 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);
- }
-
-
-
-
-
-
-
-
-
-
-
- public static ViewHolder get(Context context, View convertView,ViewGroup parent, int layoutId, int position)
- {
- if (convertView == null){
-
- return new ViewHolder(context, parent, layoutId, position);
- }
- return (ViewHolder)convertView.getTag();
- }
-
- public View getConvertView()
- {
- return mConvertView;
- }
-
-
-
-
-
-
-
-
- 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;
- }
-
-
-
-
-
-
-
-
-
- public ViewHolder setText(int viewId, String text)
- {
- TextView view = getView(viewId);
- view.setText(text);
- return this;
- }
-
-
-
-
-
-
-
-
-
- public ViewHolder setImageResource(int viewId, int drawableId)
- {
- ImageView view = getView(viewId);
- view.setImageResource(drawableId);
- return this;
- }
-
-
-
-
-
-
-
-
- public ViewHolder setImageBitmap(int viewId, Bitmap bm)
- {
- ImageView view = getView(viewId);
- view.setImageBitmap(bm);
- 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;
-
-
-
-
-
-
- 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();
- }
- }
-
-
-
-
-
-
-
-
-
-
-
- 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);
- v.setMinimumWidth(dm.widthPixels);
- TextView tv = (TextView) v.findViewById(R.id.tv_lable);
- tv.setText(text);
- result.setView(v);
- result.setDuration(duration);
-
- 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>
个人中心界面:
关于其他技术点,日后总结了看有没有必要给大家再介绍下,先就到这里吧!
源码下载:http://download.csdn.net/download/gao_chun/8861137
【注:转载注明gao_chun的BLOG http://blog.csdn.net/gao_chun/article/details/46711649】
0 0