Android练习之ImageAdapter

 

资源包:范例练习b5 FLExB5.rar

需求分析:

1.ImageAdapter的练习:

  i.容器Gallery设置ImageAdapter,效果就是拖动展示图片

  ii.ImageAdapter继承BaseAdapter,重写父类方法,主要的就是getView取得要显示的View

  iii.图片来源数组取得图片两种来源:系统图、自定图

总结吐槽:

1.图片名字不能用数字,因为他要自动生成R文件,然后然后那个R就会以文件名作变量名,然后然后就会错了...

2.想到了什么 这时候已经忘了 好自为之吧

 

View Code
  1 package com.example.flexb5;
  2 
  3 import android.os.Bundle;
  4 import android.app.Activity;
  5 import android.content.Context;
  6 import android.graphics.Color;
  7 import android.view.Menu;
  8 import android.view.View;
  9 import android.view.ViewGroup;
 10 import android.widget.BaseAdapter;
 11 import android.widget.Gallery;
 12 import android.widget.ImageView;
 13 import android.widget.TextView;
 14 
 15 public class MainActivity extends Activity {
 16     
 17     private TextView tv;
 18     private Gallery ga;
 19 
 20     @Override
 21     public void onCreate(Bundle savedInstanceState) {
 22         super.onCreate(savedInstanceState);
 23         setContentView(R.layout.activity_main);
 24         
 25         //TextView
 26         tv = (TextView)findViewById(R.id.tv_a);
 27         tv.setBackgroundColor(Color.BLACK);
 28         tv.setTextColor(Color.WHITE);
 29         tv.setText(R.string.hello_world);
 30         
 31         //Gallery
 32         ga = (Gallery)findViewById(R.id.gallery_a);
 33         ga.setAdapter(new ImageAdapter(this));
 34     }
 35 
 36     @Override
 37     public boolean onCreateOptionsMenu(Menu menu) {
 38         getMenuInflater().inflate(R.menu.activity_main, menu);
 39         return true;
 40     }
 41     
 42     //Adapter
 43     public class ImageAdapter extends BaseAdapter{
 44         
 45         private Context mycontext;
 46         
 47         public ImageAdapter(Context c){
 48             this.mycontext = c;
 49         };
 50         
 51         //图片来源之系统图片
 52         private int[] imageIds = { android.R.drawable.btn_minus,
 53                 android.R.drawable.btn_radio,
 54                 android.R.drawable.ic_lock_idle_low_battery,
 55                 android.R.drawable.ic_menu_camera,
 56                 android.R.drawable.btn_dialog};
 57         
 58         //图片来源之自定义图片
 59         private int[] imageIds2 = { R.drawable.x1,
 60                 R.drawable.x2,
 61                 R.drawable.x3,
 62                 R.drawable.x4,
 63                 R.drawable.x5
 64         };
 65         
 66 
 67         //得到已定义的图片的总数量
 68         @Override
 69         public int getCount() {
 70             return this.imageIds.length;
 71         }
 72 
 73         //得到目前容器中图片的数组
 74         @Override
 75         public Object getItem(int position) {
 76             return position;
 77         }
 78         
 79         //得到目前容器中图片的数组ID
 80         @Override
 81         public long getItemId(int position) {
 82             return position;
 83         }
 84 
 85         //得到view
 86         @Override
 87         public View getView(int position, View convertView, ViewGroup parent) {
 88             ImageView iv = new ImageView(this.mycontext);
 89             //图片来源
 90             iv.setImageResource(this.imageIds2[position]);
 91             //填充方式:拉伸至view的宽高
 92             iv.setScaleType(ImageView.ScaleType.FIT_XY);
 93             //重新设置Layout的宽高
 94             iv.setLayoutParams(new Gallery.LayoutParams(240,240));
 95             return iv;
 96         }
 97         
 98         //根据距离中央的位移量 利用getScale()返回view的大小
 99         public float getScale(boolean focused, int offset) {
100             return Math.max(0, 1.0f / (float) Math.pow(2, Math.abs(offset)));
101         }
102         
103         
104     }
105 }

 

-------------关于分辨率问题-------------

http://wenzongliang.iteye.com/blog/1499654

View Code
  1 andorid界面单位开发是应该是dip。不要出现决定坐标,和绝对的值。
  2 自适应,包括元素大小自适应,和元素位置自适应。
  3 1.关键点在于用dip,或者先判断特定手机的宽和高。总之一句话像素无关。
  4 2.每个平台一套图片,一套尺寸。
  5 元素大小:
  6 dip会自适应。
  7 图片默认会自适应的。
  8 自适应问题。一个公式 px=dip*(density/160);(density/160)在android系统中对应 DisplayMetrics.density在一固定的手机上它是一个常数,0.75,1,1.5。等。有了这个常数用dip做单位在不同手机上就有不同的px了。这就是缩放原理。dip=px/这个常数。
  9 drawable-hdpi、drawable-mdpi、drawable-ldpi中的图片是自动选择的。但是如果对应的文件夹下没有所需的图片它会在其他两个文件夹下寻找,找到了按density缩放。
 10 元素位置坐标:
 11 元素位置坐标,和触屏事件坐标, 用相对坐标。以屏幕的四边为基本相对位置。
 12  
 13  
 14 自适应原则:图片缩放自适应,位置用相对位置(单位也用dip)。
 15 所有的机型宽都是相等的dip数,高不一定是相等的dip数。
 16  
 17 240x320 density=120 320dipx426.6dip
 18 320x480 density=160 320dipx480dip
 19 480x800 density=240 320dipx533.3dip
 20 480x854 density=240 320dipx569.33dip
 21  
 22         我感觉,做手机的屏幕自适应比做web的浏览器兼容更麻烦..以下是搜到的资料,原来android还有这些不为人知的东西:
 23 一:不同的layout
 24 Android手机屏幕大小不一,有480x320, 640x360, 800x480.怎样才能让App自动适应不同的屏幕呢? 
 25    其实很简单,只需要在res目录下创建不同的layout文件夹,比如layout-640x360,layout-800x480,所有的layout文件在编译之后都会写入R.java里,而系统会根据屏幕的大小自己选择合适的layout进行使用。
 26 二:hdpi、mdpi、ldpi
 27 在之前的版本中,只有一个drawable,而2.1版本中有drawable-mdpi、drawable-ldpi、drawable-hdpi三个,这三个主要是为了支持多分辨率。
 28   drawable- hdpi、drawable- mdpi、drawable-ldpi的区别:
 29   (1)drawable-hdpi里面存放高分辨率的图片,如WVGA (480x800),FWVGA (480x854)
 30   (2)drawable-mdpi里面存放中等分辨率的图片,如HVGA (320x480)
 31   (3)drawable-ldpi里面存放低分辨率的图片,如QVGA (240x320)
 32   系统会根据机器的分辨率来分别到这几个文件夹里面去找对应的图片。
 33   在开发程序时为了兼容不同平台不同屏幕,建议各自文件夹根据需求均存放不同版本图片。
 34  
 35  
 36  
 37 
 38  
 39 
 40  
 41  
 42 1.术语和概念
 43 术语
 44 说明
 45 备注
 46 Screen size(屏幕尺寸)
 47 指的是手机实际的物理尺寸,比如常用的2.8英寸,3.2英寸,3.5英寸,3.7英寸
 48 摩托罗拉milestone手机是3.7英寸
 49 Aspect Ratio(宽高比率)
 50 指的是实际的物理尺寸宽高比率,分为long和nolong
 51 Milestone是16:9,属于long
 52 Resolution(分辨率)
 53 和电脑的分辨率概念一样,指手机屏幕纵、横方向像素个数
 54 Milestone是854*480
 55 DPI(dot per inch)
 56 每英寸像素数,如120dpi,160dpi等,假设QVGA(320*240)分辨率的屏幕物理尺寸是(2英寸*1.5英寸),dpi=160
 57 可以反映屏幕的清晰度,用于缩放UI的
 58 Density(密度)
 59 屏幕里像素值浓度,resolution/Screen size可以反映出手机密度,
 60  
 61 Density-independent pixel (dip)
 62 指的是逻辑密度计算单位,dip和具体像素值的对应公式是dip/pixel=dpi值/160,也就是px = dp * (dpi / 160)
 63  
 64  
 65 2. DPI值计算
 66 比如:计算WVGA(800*480)分辨率,3.7英寸的密度DPI,如图1所示
 67  
 68  
 69                图1 
 70 Diagonal pixel表示对角线的像素值(=),DPI=933/3.7=252
 71  
 72  
 73  
 74 3.手机屏幕的分类
 75  
 76 3.1根据手机屏幕密度(DPI)或屏幕尺寸大小分为以下3类,如图2所示
 77  
 78  
 79                          
 80                           图2
 81  
 82 3. 2手机屏幕分类和像素密度的对应关系如表1所示:
 83  
 84 Low density (120), ldpi
 85 Medium density (160), mdpi
 86 High density (240), hdpi
 87 Small screen
 88 QVGA (240x320)
 89  
 90  
 91 Normal screen
 92 WQVGA400 (240x400)WQVGA432 (240x432)
 93 HVGA (320x480)
 94 WVGA800 (480x800)WVGA854 (480x854)
 95 Large screen
 96  
 97 WVGA800* (480x800)WVGA854* (480x854)
 98  
 99                                       表1
100 3.3手机尺寸分布情况(http://developer.android.com/resources/dashboard/screens.html)如图3所示,目前主要是以分辨率为800*480和854*480的手机用户居多
101 
102  
103                                                         图3
104    从以上的屏幕尺寸分布情况上看,其实手机只要考虑3-4.5寸之间密度为1和1.5的手机
105 4 UI设计
106 从开发角度讲,应用程序会根据3类Android手机屏幕提供3套UI布局文件,但是相应界面图标也需要提供3套,如表2所示
107 Icon Type
108 Standard Asset Sizes (in Pixels), for Generalized Screen Densities
109  
110 Low density screen (ldpi)
111 Medium density screen (mdpi)
112 High density screen (hdpi)
113 Launcher
114 36 x 36 px
115 48 x 48 px
116 72 x 72 px
117 Menu
118 36 x 36 px
119 48 x 48 px
120 72 x 72 px
121 Status Bar
122 24 x 24 px
123 32 x 32 px
124 48 x 48 px
125 Tab
126 24 x 24 px
127 32 x 32 px
128 48 x 48 px
129 Dialog
130 24 x 24 px
131 32 x 32 px
132 48 x 48 px
133 List View
134 24 x 24 px
135 32 x 32 px
136 48 x 48 px
137                                         表2
138 5 如何做到自适应屏幕大小呢?
139 1)界面布局方面 
140    需要根据物理尺寸的大小准备5套布局,layout(放一些通用布局xml文件,比如界面中顶部和底部的布局,不会随着屏幕大小变化,类似windos窗口的title bar),layout-small(屏幕尺寸小于3英寸左右的布局),layout-normal(屏幕尺寸小于4.5英寸左右),layout-large(4英寸-7英寸之间),layout-xlarge(7-10英寸之间)
141 2)图片资源方面 
142   需要根据dpi值准备5套图片资源,drawable,drawalbe-ldpi,drawable-mdpi,drawable-hdpi,drawable-xhdpi
143 Android有个自动匹配机制去选择对应的布局和图片资源
144  
145 今天一个开发者问到我为什么游戏开发要删除项目下的hdpi、mdpi和ldpi文件夹;下面详细给大家解答一下:
146          首先童鞋们如果看过我写的《【Android游戏开发二十一】Android os设备谎言分辨率的解决方案!》这一节的话都应该知道Android从1.6和更高,Google为了方便开发者对于各种分辨率机型的移植而增加了自动适配的功能;
147         自动适配的原理很简单,只要你建立的项目是1.6或者更高都会看到项目下有drawable-hdpi、drawable-mdpi、drawable-ldpi 三个文件夹,这三个文件夹分别放置高清分辨率、中分辨率、低分辨率的资源文件;那么如果你的项目在高清分辨率上运行的话,系统会默认索引drawable-hdpi文件夹下的资源,其他雷同;
148          那么既然系统会自动找匹配的文件夹,那么肯定会出现找不到的情况,比如当前你的应用在高清分辨率运行,假设代码中加载一张“himi.png”的图,那么系统首先会去drawable-hdpi文件夹下去找这张图,一旦找不到,系统会再到其他drawable下寻找,再假设你其实把这张“himi.png”放在了drawable-mdpi中,那么系统会默认把这张图片放大;反之一样,如果你在低分辨率中运行加载一张图片的话,一旦你将图片放入高清的drawable-dpi中,那么系统默认缩小这张图;
149         总结来说:如果你的应用想适配高、中、低分辨率,那么你需要有3套图放入对应的文件夹中,这样系统会智能加载;如果你就想保留一个文件夹,不想让系统智能寻找缩放的话,有两种方式可以解决:
150        1.删除drawable-hdpi、drawable-mdpi、drawable-ldpi三个文件夹,创建一个drawable文件夹即可;
151        2.将资源文件放入assets中,因为assets中的资源系统永远不会为其生成id,所以不会智能缩放;
152       -------------------下面介绍第二点,如何让你的游戏应用高清
153       其实还是在《【Android游戏开发二十一】Android os设备谎言分辨率的解决方案!》中介绍过,1.6后android有了智能判断的缘故,你获取的屏幕宽高其实是不准确的,详情可以参考【Android游戏开发二十一】Android os设备谎言分辨率的解决方案!》;那么这里要补充一点就是:
154       如果你在AndroidMainFest 中,定义  <uses-sdk android:minSdkVersion="4" /> 就OK了!你会发现你的图片很清楚,其实也是因为android自动缩放造成的,上面说了,一般获取的分辨率会不正常(比正确的偏小)那么一旦你加上这一句之后,你的分辨率就正常了,所以就明显游戏质量高了一个档次。
155 
156        这里再补充一下: 一旦你定义了<uses-sdk android:minSdkVersion="4" />,就是限制1.5SDK的手机无法安装你的程序;
157 
158       OK,继续忙了,大家尝试下吧~
159  
160 1.Screen size 屏幕实际尺寸。
161 Android讲屏幕实际尺寸分为3个通用的尺寸。
162    
163    2.Aspect ratio 长宽比
164 
165    3.Resolution 分辨率
166 
167    4.Density 密度
168 
169    5.Density-independent pixel 密度无关的像素
170 
171 介绍:Adnroid1.6或以上SDK,在AndroidManifest.xml中提供新的一个元素<supports-screens>用于支持多屏幕机制。
172      <supports-screens 
173               android:largeScreens="true"   是否支持大屏
174                android:normalScreens="true"  是否支持中屏
175                android:smallScreens="true"   是否支持小屏
176                android:anyDensity="true"     是否支持多种不同密度
177      /> 
178 
179 
180 Android提供3种方式处理屏幕自适应
181      一.预缩放的资源(基于尺寸和密度去寻找图片)
182          1.如果找到相应的尺寸和密度,则利用这些图片进行无缩放小时。
183          2.如果没法找到相应的尺寸,而找到密度,则认为该图片尺寸为 "medium",利用缩放这个图片显示。
184          3.如果都无法匹配,则使用默认图片进行缩放显示。默认图片默认标配 "medium" (160)。
185 
186      二.自动缩放的像素尺寸和坐标(密度兼容)
187          1.如果应用程序不支持不同密度android:anyDensity="false",系统自动缩放图片尺寸和这个图片的坐标。
188           (代码中体现)
189          2.对于预缩放的资源,当android:anyDensity="false",也不生效。
190          3.android:anyDensity="false",只对密度兼容起作用,尺寸兼容没效果
191 
192      三.兼容模式显示在大屏幕,尺寸(尺寸兼容)
193          1.对于你在<supports-screens>声明不支持的大屏幕,而这个屏幕尺寸是normal的话,系统使用尺寸为            ("normal")和密度为("medium)显示。
194          2. 对于你在<supports-screens>声明不支持的大屏幕,而这个屏幕尺寸是larger的话,系统同样使用尺寸为                   ("normal")和密度为("medium)显示,不过会出现一层黑色的背景。不是居中显示。
195 
196 
197 密度独立:
198      系统默认应用支持DIP单位的,三个使用DIP的地方:
199          1.加载资源时,使用DIP实现预缩放的资源。
200          2.在Layout使用DIP,系统自动完成缩放。
201          3.在应用程序中,自动缩放一些绝对像素。
202             (只有在android:anyDensity="false"生效)即屏幕自适应方式二
203          4.像素单位都使用DIP,文本单位使用SP
204 
205 最佳屏幕独立实践:
206      1.使用wrap_content, fill_parent 和使用dip作为像素单位in XML layout files。
207      2.避免使用AbsoluteLayout 
208      3.在代码中,不要使用像素数字硬编码,而是要通过dip转换为px。
209          例子:
210        你使用手势分析器分析一个scroll手势,假如,你滚动的距离是16px。
211          1.在一个160dip的屏幕中,你实际移动距离 16px / 160dpi = 1/10th of an inch (or 2.5 mm)
212          2.在一个240dip的屏幕中,你实际移动距离 16px / 240dpi = 1/15th of an inch (or 1.7 mm)
213           // The gesture threshold expressed in dip 
214           private static final float GESTURE_THRESHOLD_DIP = 16.0f; 
215            // Convert the dips to pixels 
216            final float scale = getContext().getResources().getDisplayMetrics().density; 
217            mGestureThreshold = (int) (GESTURE_THRESHOLD_DIP * scale); 
218      4.使用密度和/或尺寸特定资源(通过文件夹)
219 
220 
221 关于预缩放或者自动缩放图片或9格图
222      1.系统是一定对会资源包下的图片进行合理的缩放。
223         例如:一张240x240高密度图片,显示在中密度的屏幕上,图片大小自动变为160x160。
224      2.你在API中不会得到被缩放后的图片尺寸,得到还是你原来图片的尺寸。
225      3.如果你不想系统自动帮你缩放图片,可以建立一个res/drawable-nodpi文件夹,存放你的图片。
226      4.也可以通过BitmapFactory.Options 完成系统自动缩放图片或9格图(在画图时)。
227      5.自动缩放图片比预缩放花费更多CPU,但是用更少内存(RAM or ROM ?)
228  
229  
230 一、相关概念
231 a)       android支持density的版本
232 Android从1.6版本开始支持density(对应API Level 4)
233 b)       density
234 density值表示每英寸有多少个显示点,比如240就是每英寸240个点,它是针对设备的属性,它是屏幕物理长宽的扩展,给屏幕设置为低密度显示的内容少,同样的条件下,密度小的屏幕显示同样的按钮看起来大,高密度的看起来小
235 c)       分辨率
236 是整个屏是多少点,比如800x480,它是对于软件来说的显示单位,以px为单位的点
237 d)       设置density的效果
238 不同density下屏幕分辨率信息,以480dip*800dip的WVGA为例
239 density=120时 屏幕实际分辨率为240px*400px
240 density=160时 屏幕实际分辨率为320px*533px
241 density=240时 屏幕实际分辨率为480px*800px
242 二、相关代码及设置
243 a)       AndroidManifest.xml
244 <supports-screens android:anyDensity="true"/>
245 <uses-sdk android:minSdkVersion="4">uses-sdk>
246 b)       资源目录名(android 2.0以后)
247 res/xxx-hdpi    当density为240时,使用此目录下的资源
248 res/xxx-mdpi    当density为160时,使用此目录下的资源
249 res/xxx-ldpi    当density为120时,使用此目录下的资源
250 res/xxx     不常后缀,为默认设置,同xxx-mdpi
251 如果硬件相应的desity的目录不存在,系统会利用存在的density自动乘以系数计算出相应的density
252 c)       资源单位(layout xml文件中定义大小的单位)
253                      i.              dp=dip=dx   (Density independent pixel)
254 基于屏幕密度的抽象单位,布局时尽量使用单位dip,少使用px
255 dip是应用用于定义UI的虚拟单位,用于说明与密度无关的尺寸和位置。
256 dip点等价于160dpi密度中的一个物理点,密度由平台决定,换算公式如下
257 pixels = dips * (density / 160),160DPI的密度系数是1
258 例如 240 dpi的屏幕,1个dip点等于1.5个物理点
259                   ii.              px
260 设置的绝对点数, 如果使用更高density的系统, 控件就会变小
261 三、设置density
262 设置系统变量hw.lcd.density,可设置density
263 四、实现density的关键源码
264 a)       BitmapFactory.java
265 b)       ComptibilityInfo.java
266 五、参考
267 a)       http://www.cnmsdn.com/html/201005/1275315384ID5529.html

 

转载于:https://www.cnblogs.com/imzzh/archive/2012/11/05/2755432.html

你可能感兴趣的:(Android练习之ImageAdapter)