Android项目结构与分析源码,其中的秘密,你知道吗?

2016-04-28 15:10 阅读 4,980 次 评论 0 条
版权声明:本文著作权归TeachCourse所有,未经许可禁止转载,谢谢支持!
转载请注明出处:http://teachcourse.cn/1704.html

一、摘要

Android项目结构无非是res和src这两个文件夹,src主要Java代码,res放置资源文件,Eclipse默认生成的资源文件包括:drawable、layout、values、menu,关于还可以存放哪个类型的资源文件呢?打开SDK路径下的platforms文件夹,随便打开一个平台,比如:android-23,如下路径——“E:\adt-bundle-windows-x86_64-20140702\sdk\platforms\android-23\data\res”,找到res文件夹,这里展示所有该平台开发需要的资源。

二、分析res结构

在打开的res文件夹下,看到了其他在Eclipse创建项目时无法自动生成的anim、animator、color文件夹,这些文件夹在实际的项目开发中可以手动添加,存放的内容和系统提供的内容类型一样,于是我们可以在自己项目的res中重写。

如何重写系统的默认属性?举一个例子:重写Spinner控件的默认样式和下拉选项样式。

上面我们讲解了Android项目结构,了解每个res下属文件夹的作用,那样我们修改起来显得很方便了。上面例子想要修改Spinner样式,重写android:background=""属性可以完成,这里需要注意的是,添加什么样的属性值合适呢?

如果你不清楚怎么添加属性值,添加什么样的属性值合适,可以打开源码下的Spinner控件默认属性android:background=""属性值添加方式(需要说明的系统所有控件样式定义在Style.xml文件,组件样式定义在Themes.xml,控件属性定义在attrs.xml),EditPlus(下载)打开style.xml文件,Ctrl+F找到Spinner控件,如下图:
001-widget-spinner

看到选项:@drawable/btn_dropdown即系统定义的默认Spinner的background属性,属性值btn_dropdown.xml文件,找到该文件,如下图:
002-btn_dropdown

可以看到该文件是一个selector选择器,在drawabl-xhdpi.xml文件夹指定背景:btn_dropdown_normal.png,背景是一张.9图片,如下图:
btn_dropdown_normal.9

根据Spinner控件状态选择不同背景,我们要做的是:复制该文件到自己项目res/drawable中,修改各状态的背景样式(重写属性值),和美工商量定制一张自己“梦想”的背景:btn_dropdown_normal.png,最后引用定制的背景即可(这里使用blue_bg.9.png代替btn_dropdown_pressed.9.png),运行效果如下图:
override-values-demo

重写Spinner默认字体颜色

在Spinner中未提供android:textColor=""属性,就好像ListView一样,提供适配器指定布局、内容的方式修改字体颜色,Spinner和ListView不同的是:Spinner有下拉选项布局和默认布局,


ArrayAdapter绑定数据的代码如下:

  1. /**第一种添加数据的方式 
  2.      * @return ArrayAdapter对象 
  3.      */  
  4.     private ArrayAdapter<String> setArrayAdapter() {  
  5.         // 建立数据源  
  6.         String[] mItems = getResources().getStringArray(R.array.citys);  
  7.         // 建立Adapter并且绑定数据源  
  8.         ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,  
  9.                 R.layout.simple_spinner_item, mItems);  
  10.         adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);  
  11.   
  12.         return adapter;  
  13.     }  


BaseAdapter绑定数据的代码如下:

  1. /**第二种添加数据的方式 
  2.      * @return BaseAdapter对象 
  3.      */  
  4.     private BaseAdapter setBaseAdapter() {  
  5.   
  6.         CityBean city = new CityBean();  
  7.         city.setCity("北京");  
  8.         mList.add(city);  
  9.   
  10.         CityBean city2 = new CityBean();  
  11.         city2.setCity("上海");  
  12.         mList.add(city2);  
  13.   
  14.         CityBean city3 = new CityBean();  
  15.         city3.setCity("广州");  
  16.         mList.add(city3);  
  17.   
  18.         CityBean city4 = new CityBean();  
  19.         city4.setCity("深圳");  
  20.         mList.add(city4);  
  21.         MyBaseAdapter adapter = new MyBaseAdapter(this, mList);  
  22.           
  23.         return adapter;  
  24.     }  
  1. package cn.teachcourse.adapter;  
  2.   
  3. import java.util.List;  
  4.   
  5. import android.content.Context;  
  6. import android.view.LayoutInflater;  
  7. import android.view.View;  
  8. import android.view.ViewGroup;  
  9. import android.widget.BaseAdapter;  
  10. import android.widget.TextView;  
  11. import cn.teachcourse.bean.CityBean;  
  12. import cn.teachcourse.main.R;  
  13.   
  14. /* 
  15. @author TeachCourse 
  16. @date 创建于:2015-12-14 
  17.  */  
  18. public class MyBaseAdapter extends BaseAdapter {  
  19.     private Context context;  
  20.     private List<CityBean> mList;  
  21.       
  22.     public MyBaseAdapter(Context context,List<CityBean> mList) {  
  23.         this.context=context;  
  24.         this.mList=mList;  
  25.     }  
  26.     @Override  
  27.     public int getCount() {  
  28.         if(mList!=null){  
  29.             return mList.size();  
  30.         }  
  31.               
  32.             return 0;  
  33.           
  34.     }  
  35.   
  36.     @Override  
  37.     public Object getItem(int position) {  
  38.         if(mList!=null){  
  39.             return mList.get(position);  
  40.         }  
  41.         return null;  
  42.     }  
  43.   
  44.     @Override  
  45.     public long getItemId(int position) {  
  46.           
  47.         return position;  
  48.     }  
  49.   
  50.     @Override  
  51.     public View getView(int position, View convertView, ViewGroup parent) {  
  52.           
  53.         ViewHolder mViewHolder;  
  54.         if(convertView==null){//初始化convertView  
  55.             LayoutInflater mInflater=LayoutInflater.from(context);  
  56.             convertView=mInflater.inflate(R.layout.simple_spinner_item, parent,false);  
  57.             mViewHolder=new ViewHolder();  
  58.             mViewHolder.mTextView=(TextView) convertView.findViewById(R.id.text1);  
  59.             convertView.setTag(mViewHolder);  
  60.         }else{  
  61.             mViewHolder=(ViewHolder) convertView.getTag();  
  62.         }  
  63.         mViewHolder.mTextView.setText(mList.get(position).getCity());  
  64.         return convertView;  
  65.     }  
  66.       
  67.     static class ViewHolder{  
  68.          TextView mTextView;  
  69.     }  
  70.       
  71. }  


SpinnerAdapter绑定数据的代码如下:

  1. package cn.teachcourse.adapter;  
  2.   
  3. import java.util.List;  
  4.   
  5. import cn.teachcourse.adapter.MyBaseAdapter.ViewHolder;  
  6. import cn.teachcourse.bean.CityBean;  
  7. import cn.teachcourse.main.R;  
  8. import android.content.Context;  
  9. import android.database.DataSetObserver;  
  10. import android.view.LayoutInflater;  
  11. import android.view.View;  
  12. import android.view.ViewGroup;  
  13. import android.widget.CheckedTextView;  
  14. import android.widget.SpinnerAdapter;  
  15. import android.widget.TextView;  
  16.   
  17. /* 
  18.  @author TeachCourse 
  19.  @date 创建于:2015-12-14 
  20.  */  
  21. public class MySpinnerAdapter implements SpinnerAdapter {  
  22.     private Context context;  
  23.     private List<CityBean> mList;  
  24.   
  25.     public MySpinnerAdapter(Context context, List<CityBean> mList) {  
  26.         this.context = context;  
  27.         this.mList = mList;  
  28.     }  
  29.   
  30.     @Override  
  31.     public void registerDataSetObserver(DataSetObserver observer) {  
  32.         // TODO Auto-generated method stub  
  33.   
  34.     }  
  35.   
  36.     @Override  
  37.     public void unregisterDataSetObserver(DataSetObserver observer) {  
  38.         // TODO Auto-generated method stub  
  39.   
  40.     }  
  41.   
  42.     @Override  
  43.     public int getCount() {  
  44.         if(mList!=null){  
  45.             return mList.size();  
  46.         }  
  47.         return 0;  
  48.     }  
  49.   
  50.     @Override  
  51.     public Object getItem(int position) {  
  52.         if(mList!=null){  
  53.             return mList.get(position);  
  54.         }  
  55.         return null;  
  56.     }  
  57.   
  58.     @Override  
  59.     public long getItemId(int position) {  
  60.         if(mList!=null){  
  61.             return position;  
  62.         }  
  63.         return 0;  
  64.     }  
  65.   
  66.     @Override  
  67.     public boolean hasStableIds() {  
  68.         // TODO Auto-generated method stub  
  69.         return false;  
  70.     }  
  71.   
  72.     @Override  
  73.     public View getView(int position, View convertView, ViewGroup parent) {  
  74.         ViewHolder mViewHolder;  
  75.         if(convertView==null){//初始化convertView  
  76.             LayoutInflater mInflater=LayoutInflater.from(context);  
  77.             convertView=mInflater.inflate(R.layout.simple_spinner_item, parent,false);  
  78.             mViewHolder=new ViewHolder();  
  79.             mViewHolder.mTextView=(TextView) convertView.findViewById(R.id.text1);  
  80.             convertView.setTag(mViewHolder);  
  81.         }else{  
  82.             mViewHolder=(ViewHolder) convertView.getTag();  
  83.         }  
  84.         mViewHolder.mTextView.setText(mList.get(position).getCity());  
  85.         return convertView;  
  86.     }  
  87.       
  88.     static class ViewHolder{  
  89.          TextView mTextView;  
  90.     }  
  91.   
  92.     @Override  
  93.     public int getItemViewType(int position) {  
  94.         // TODO Auto-generated method stub  
  95.         return 0;  
  96.     }  
  97.   
  98.     @Override  
  99.     public int getViewTypeCount() {  
  100.         // TODO Auto-generated method stub  
  101.         return 0;  
  102.     }  
  103.   
  104.     @Override  
  105.     public boolean isEmpty() {  
  106.         // TODO Auto-generated method stub  
  107.         return false;  
  108.     }  
  109.   
  110.     @Override  
  111.     public View getDropDownView(int position, View convertView, ViewGroup parent) {  
  112.         LayoutInflater inflate=LayoutInflater.from(context);  
  113.         View view =inflate.inflate(R.layout.simple_spinner_dropdown_item, parent, false);  
  114.         CheckedTextView checked=(CheckedTextView)view.findViewById(R.id.dropdown_item_id);  
  115.         checked.setText(mList.get(position).getCity());  
  116.         return view;  
  117.     }  
  118. }  

区别:

ArrayAdapter和SpinnerAdapter绑定数据的方式可以手动定义Spinner下拉列表样式和默认样式:ArrayAdapter使用setDropDownViewResource(int)方法,SpinnerAdapter使用回调方法getDropDownView(),如上面代码。

BaseAdapter只可以手动定义默认样式(暂不清楚怎么设置下拉列表),但BaseAdapter使用方法和SpinnerAdapter一样,推荐使用SpinnerAdapter。

修改Spinner控件颜色、样式和调整大小都不是啥事,只需要定义simple_spinner_item.xml布局和simple_spinner_dropdown_item.xml即可

关注公众号 扫一扫二维码,加我QQ

如果文章对你有帮助,欢迎点击上方按钮关注作者

来源:TeachCourse每周一次,深入学习Android教程,关注(QQ1589359239或公众号TeachCourse)
转载请注明出处:http://teachcourse.cn/1704.html

资源分享

Spinner修改样式源码下载
分类:Android, Java基础 标签:, ,
Android开发之混淆基础教程 Android开发之混淆基础教程
MVP设计模式嵌入百度地图小结 MVP设计模式嵌入百度地图小结
很抱歉“com.huawei.lcagent”已停止运行解决办法 很抱歉“com.huawei.lcagent”已
Android开发工程师笔试题–001 Android开发工程师笔试题--001

发表评论

呲牙 憨笑 坏笑 偷笑 色 微笑 抓狂 睡觉 酷 流汗 鼓掌 大哭 可怜 疑问 晕 惊讶 得意 尴尬 发怒 奋斗 衰 骷髅 啤酒 吃饭 礼物 强 弱 握手 OK NO 勾引 拳头 差劲 爱你

表情