1.自定义BaseAdapter,而后绑定ListView的最简单例子
先看看咱们要实现的效果图:
一个很简单的ListView,本身写下Item,而后加载点数据这样~ 下面贴下关键代码:java
Animal.java:android
public class Animal { private String aName; private String aSpeak; private int aIcon; public Animal() { } public Animal(String aName, String aSpeak, int aIcon) { this.aName = aName; this.aSpeak = aSpeak; this.aIcon = aIcon; } public String getaName() { return aName; } public String getaSpeak() { return aSpeak; } public int getaIcon() { return aIcon; } public void setaName(String aName) { this.aName = aName; } public void setaSpeak(String aSpeak) { this.aSpeak = aSpeak; } public void setaIcon(int aIcon) { this.aIcon = aIcon; } }
AnimalAdapter.java:自定义的BaseAdapter:canvas
public class AnimalAdapter extends BaseAdapter { private LinkedList<Animal> mData; private Context mContext; public AnimalAdapter(LinkedList<Animal> mData, Context mContext) { this.mData = mData; this.mContext = mContext; } @Override public int getCount() { return mData.size(); } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { convertView = LayoutInflater.from(mContext).inflate(R.layout.item_list_animal,parent,false); ImageView img_icon = (ImageView) convertView.findViewById(R.id.img_icon); TextView txt_aName = (TextView) convertView.findViewById(R.id.txt_aName); TextView txt_aSpeak = (TextView) convertView.findViewById(R.id.txt_aSpeak); img_icon.setBackgroundResource(mData.get(position).getaIcon()); txt_aName.setText(mData.get(position).getaName()); txt_aSpeak.setText(mData.get(position).getaSpeak()); return convertView; } }
最后是MainActivity.java:app
public class MainActivity extends AppCompatActivity { private List<Animal> mData = null; private Context mContext; private AnimalAdapter mAdapter = null; private ListView list_animal; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mContext = MainActivity.this; list_animal = (ListView) findViewById(R.id.list_animal); mData = new LinkedList<Animal>(); mData.add(new Animal("狗说", "你是狗么?", R.mipmap.ic_icon_dog)); mData.add(new Animal("牛说", "你是牛么?", R.mipmap.ic_icon_cow)); mData.add(new Animal("鸭说", "你是鸭么?", R.mipmap.ic_icon_duck)); mData.add(new Animal("鱼说", "你是鱼么?", R.mipmap.ic_icon_fish)); mData.add(new Animal("马说", "你是马么?", R.mipmap.ic_icon_horse)); mAdapter = new AnimalAdapter((LinkedList<Animal>) mData, mContext); list_animal.setAdapter(mAdapter); } }
好的,自定义BaseAdapter以及完成数据绑定就是这么简单~
别问我拿示例的代码,刚开始学就会写出这些代码,我只是演示下流程,让你们熟悉 熟悉而已~另外,也是为下面的属性验证作准备~
2.表头表尾分割线的设置:
listview做为一个列表控件,他和普通的列表同样,能够本身设置表头与表尾: 以及分割线,可供咱们设置的属性以下:ide
footerDividersEnabled:是否在footerView(表尾)前绘制一个分隔条,默认为true
headerDividersEnabled:是否在headerView(表头)前绘制一个分隔条,默认为true
divider:设置分隔条,能够用颜色分割,也能够用drawable资源分割
dividerHeight:设置分隔条的高度
翻遍了了API发现并无能够直接设置ListView表头或者表尾的属性,只能在Java中写代码 进行设置了,可供咱们调用的方法以下:布局
addHeaderView(View v):添加headView(表头),括号中的参数是一个View对象
addFooterView(View v):添加footerView(表尾),括号中的参数是一个View对象
addHeaderView(headView, null, false):和前面的区别:设置Header是否能够被选中
addFooterView(View,view,false):同上
对了,使用这个addHeaderView方法必须放在listview.setAdapter前面,不然会报错。
post
代码实现:
先编写下表头与表尾的布局:
view_header.xml(表头),表尾同样,就不贴了:字体
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center"> <TextView android:layout_width="match_parent" android:layout_height="48dp" android:textSize="18sp" android:text="表头" android:gravity="center" android:background="#43BBEB" android:textColor="#FFFFFF"/> </LinearLayout>
MainActivty.java:ui
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener{ private List<Animal> mData = null; private Context mContext; private AnimalAdapter mAdapter = null; private ListView list_animal; private LinearLayout ly_content; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mContext = MainActivity.this; list_animal = (ListView) findViewById(R.id.list_animal); //动态加载顶部View和底部View final LayoutInflater inflater = LayoutInflater.from(this); View headView = inflater.inflate(R.layout.view_header, null, false); View footView = inflater.inflate(R.layout.view_footer, null, false); mData = new LinkedList<Animal>(); mData.add(new Animal("狗说", "你是狗么?", R.mipmap.ic_icon_dog)); mData.add(new Animal("牛说", "你是牛么?", R.mipmap.ic_icon_cow)); mData.add(new Animal("鸭说", "你是鸭么?", R.mipmap.ic_icon_duck)); mData.add(new Animal("鱼说", "你是鱼么?", R.mipmap.ic_icon_fish)); mData.add(new Animal("马说", "你是马么?", R.mipmap.ic_icon_horse)); mAdapter = new AnimalAdapter((LinkedList<Animal>) mData, mContext); //添加表头和表尾须要写在setAdapter方法调用以前!!! list_animal.addHeaderView(headView); list_animal.addFooterView(footView); list_animal.setAdapter(mAdapter); list_animal.setOnItemClickListener(this); } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Toast.makeText(mContext,"你点击了第" + position + "项",Toast.LENGTH_SHORT).show(); } }
好的,代码仍是比较简单的,从上面咱们看出来一个要注意的问题,就是:
添加表头表尾后,咱们发现positon是从表头开始算的,就是你添加的第一个数据原本的 postion 是 0,可是此时却变成了 1,由于表头也算!!this
GridView与ListView的用法基本一致,不一样的只是布局。当咱们打开手机,应用会以宫格显示,那就是GridView。
以代码形式展现给你们,适配器使用SimpleAdapter,熟悉了适配器的用法,就只须要注意几个GridView的属性便可。
Activity类
public class MainActivity extends Activity { private GridView gridView; private List<Map<String, Object>> dataList; private SimpleAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); gridView = (GridView) findViewById(R.id.gridview); //初始化数据 initData(); String[] from={"img","text"}; int[] to={R.id.img,R.id.text}; adapter=new SimpleAdapter(this, dataList, R.layout.gridview_item, from, to); gridView.setAdapter(adapter); gridView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { AlertDialog.Builder builder= new AlertDialog.Builder(MainActivity.this); builder.setTitle("提示").setMessage(dataList.get(arg2).get("text").toString()).create().show(); } }); } void initData() { //图标 int icno[] = { R.drawable.i1, R.drawable.i2, R.drawable.i3, R.drawable.i4, R.drawable.i5, R.drawable.i6, R.drawable.i7, R.drawable.i8, R.drawable.i9, R.drawable.i10, R.drawable.i11, R.drawable.i12 }; //图标下的文字 String name[]={"时钟","信号","宝箱","秒钟","大象","FF","记事本","书签","印象","商店","主题","迅雷"}; dataList = new ArrayList<Map<String, Object>>(); for (int i = 0; i <icno.length; i++) { Map<String, Object> map=new HashMap<String, Object>(); map.put("img", icno[i]); map.put("text",name[i]); dataList.add(map); } } }
**GridView主布局文件activity_main.xml** <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#000" tools:context="com.example.l7.MainActivity" > <GridView android:id="@+id/gridview" android:layout_width="match_parent" android:layout_height="wrap_content" android:columnWidth="80dp" android:stretchMode="spacingWidthUniform" android:numColumns="3" /> </LinearLayout>
列表项布局gridview_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:orientation="vertical" > <ImageView android:id="@+id/img" android:layout_width="60dp" android:layout_height="60dp" android:layout_marginTop="10dp" android:src="@drawable/ic_launcher" /> <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="2dp" android:layout_gravity="center" android:textColor="#FFF" android:text="文字" /> </LinearLayout>
效果图
样式是指为 View 或窗口指定外观和格式的属性集合。样式能够指定高度、填充、字体颜色、字号、背景色等许多属性。 样式是在与指定布局的 XML 不一样的 XML 资源中进行定义。
Android 中的样式与网页设计中层叠样式表的原理相似 — 您能够经过它将设计与内容分离。
例如,经过使用样式,您能够将如下布局 XML:
<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:textColor="#00FF00" android:typeface="monospace" android:text="@string/hello" /> 简化成这个样子: <TextView style="@style/CodeFont" android:text="@string/hello" />
布局 XML 中全部与样式有关的属性都已移除,并置于一个名为 CodeFont 的样式定义内,而后经过 style 属性加以应用。 您会在下文中看到对该样式的定义。
主题是指对整个 Activity 或应用而不是对单个 View(如上例所示)应用的样式。 以主题形式应用样式时,Activity 或应用中的每一个视图都将应用其支持的每一个样式属性。 例如,您能够 Activity 主题形式应用同一 CodeFont 样式,以后该 Activity 内的全部文本都将具备绿色固定宽度字体。
定义样式
要建立一组样式,请在您的项目的 res/values/ 目录中保存一个 XML 文件。 可任意指定该 XML 文件的名称,但它必须使用 .xml 扩展名,而且必须保存在 res/values/ 文件夹内。
该 XML 文件的根节点必须resources。
对于您想建立的每一个样式,向该文件添加一个 style 元素,该元素带有对样式进行惟一标识的 name 属性(该属性为必需属性)。而后为该样式的每一个属性添加一个 item 元素,该元素带有声明样式属性以及属性值的 name(该属性为必需属性)。 根据样式属性,item 的值能够是关键字字符串、十六进制颜色值、对另外一资源类型的引用或其余值。如下是一个包含单个样式的示例文件:
<?xml version="1.0" encoding="utf-8"?> <resources> <style name="CodeFont" parent="@android:style/TextAppearance.Medium"> <item name="android:layout_width">fill_parent</item> <item name="android:layout_height">wrap_content</item> <item name="android:textColor">#00FF00</item> <item name="android:typeface">monospace</item> </style> </resources> resources
元素的每一个子项都会在编译时转换成一个应用资源对象,该对象可由 style>元素的 name 属性中的值引用。 可从 XML 布局以 @style/CodeFont 形式引用该示例样式(如上文引言中所示)。
style 元素中的 parent 属性是可选属性,它指定应做为此样式所继承属性来源的另外一样式的资源 ID。 若是愿意,您可在随后替换这些继承的样式属性。
切记,在 XML 中定义您想用做 Activity 或应用主题的样式与定义视图样式的方法彻底相同。 诸如上文所定义的样式可做为单个视图的样式加以应用,也可做为整个 Activity 或应用的主题加以应用。 后文将阐述如何为单个视图应用样式或如何以应用主题形式应用样式。
设置样式的方法有两种:
若是是对单个视图应用样式,请为布局 XML 中的 View 元素添加 style 属性。
或者,若是是对整个 Activity 或应用来应用样式,请为 Android 清单中的 activity 或 application 元素添加 android:theme 属性。
当您对布局中的单个 View 应用样式时,该样式定义的属性只应用于该 View。 若是对 ViewGroup 应用样式,子 View 元素将不会继承样式属性 — 只有被您直接应用样式的元素才会应用其属性。 不过,您能够经过以主题形式应用样式,使所应用的样式做用于全部 View 元素。
要以主题形式应用样式定义,您必须在 Android 清单中将样式应用于 Activity 或应用。 若是您这样作,Activity 或应用内的每一个 View 都将应用其支持的每一个属性。 例如,若是您对某个 Activity 应用前面示例中的 CodeFont 样式,则全部支持这些文本样式属性的 View 元素也会应用这些属性。 任何不支持这些属性的 View 都会忽略这些属性。 若是某个 View 仅支持部分属性,将只应用这些属性。
对视图应用样式
为 XML 布局中的视图设置样式的方法以下:
< TextView style="@style/CodeFont" android:text="@string/hello" />
如今该 TextView 将按照名为 CodeFont 的样式的定义设置样式(请参阅上文定义样式中的示例)。
注:style 属性不使用 android: 命名空间前缀。
对 Activity 或应用应用主题
要为您的应用的全部 Activity 设置主题,请打开 AndroidManifest.xml 文件并application 标记,在其中加入带样式名称的 android:theme 属性。 例如:
若是您只想对应用中的一个 Activity 应用主题,则改成给
正如 Android 提供了其余内建资源同样,有许多预约义主题可供您使用,可免于自行编写。 例如,您可使用 Dialog 主题,为您的 Activity 赋予相似对话框的外观:
或者,若是您但愿背景是透明的,则可以使用 Translucent 主题:
<activity android:theme="@android:style/Theme.Translucent"> 若是您喜欢某个主题,但想作些调整,只需将该主题添加为您的自定义主题的 parent。 例如,您能够像下面这样对传统明亮主题进行修改,使用您本身的颜色: <color name="custom_theme_color">#b0b0ff</color> <style name="CustomTheme" parent="android:Theme.Light"> <item name="android:windowBackground">@color/custom_theme_color</item> <item name="android:colorBackground">@color/custom_theme_color</item> </style>
(请注意,此处颜色须要以单独资源形式提供,由于 android:windowBackground 属性仅支持对另外一资源的引用;不一样于 android:colorBackground,没法为其提供颜色字面量。)
如今,在 Android 清单内使用 CustomTheme 替代 Theme.Light:
根据平台版本选择主题
新版本的 Android 可为应用提供更多主题,您可能但愿在这些平台上运行时可使用这些新增主题,同时仍可兼容旧版本。 您能够经过自定义主题来实现这一目的,该主题根据平台版本利用资源选择在不一样父主题之间切换。
图片的处理包括如下:
1, 缩放
2, 倾斜
3, 旋转
4, 缩放+
5, 平移
6, 镜像
代码以下:
package com.mike.activity; import java.io.FileNotFoundException; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.BitmapFactory.Options; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.Display; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; public class ImageDemoActivity extends Activity implements OnClickListener { /** Called when the activity is first created. */ public static String TAG = "IMAGE"; public static int REQUEST_CODE = 0; private ImageView mImageShow; private ImageView mImageAltered; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button p_w_picpathSelectBtn = (Button) findViewById(R.id.p_w_picpathSelectBtn); mImageShow = (ImageView) findViewById(R.id.p_w_picpathShow); mImageAltered = (ImageView) findViewById(R.id.p_w_picpathAltered); p_w_picpathSelectBtn.setOnClickListener(this); } public void onClick(View v) { // TODO Auto-generated method stub Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);// 启动照片Gallery startActivityForResult(intent, 0); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { // TODO Auto-generated method stub super.onActivityResult(requestCode, resultCode, intent); if (resultCode == RESULT_OK) {// 操做成功 Uri imgFileUri = intent.getData();// 得到所选照片的信息 Log.d(TAG, "imgFileUri is :" + imgFileUri); // 因为返回的图像可能太大而没法彻底加载到内存中。系统有限制,须要处理。 Display currentDisplay = getWindowManager().getDefaultDisplay(); int defaultHeight = currentDisplay.getHeight(); int defaultWidth = currentDisplay.getWidth(); BitmapFactory.Options bitmapFactoryOptions = new BitmapFactory.Options(); bitmapFactoryOptions.inJustDecodeBounds = false;// /只是为获取原始图片的尺寸,而不返回Bitmap对象 // 注上:If set to true, the decoder will return null (no bitmap), but // the out... fields will still be set, // allowing the caller to query the bitmap without having to // allocate the memory for its pixels try { Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver() .openInputStream(imgFileUri), null, bitmapFactoryOptions); int outHeight = bitmapFactoryOptions.outHeight; int outWidth = bitmapFactoryOptions.outWidth; int heightRatio = (int) Math.ceil((float) outHeight / defaultHeight); int widthRatio = (int) Math.ceil((float) outWidth / defaultWidth); if (heightRatio > 1 || widthRatio > 1) { if (heightRatio > widthRatio) { bitmapFactoryOptions.inSampleSize = heightRatio; } else { bitmapFactoryOptions.inSampleSize = widthRatio; } } bitmapFactoryOptions.inJustDecodeBounds = false; bitmap = BitmapFactory.decodeStream(getContentResolver() .openInputStream(imgFileUri), null, bitmapFactoryOptions); mImageShow.setImageBitmap(bitmap); // /* // * 在位图上绘制位图 // */ // // Bitmap bitmapAltered = Bitmap.createBitmap(bitmap.getWidth(), // bitmap.getHeight(), bitmap.getConfig()); // // Canvas canvas = new // Canvas(bitmapAltered);//bitmap提供了画布,只在此提供了大小尺寸,偏移后并未有背景显示出来 // // // Paint paint = new Paint(); // // canvas.drawBitmap(bitmap, 0, 0, paint);//绘制的图片和以前的如出一辙 // // mImageAltered.setImageBitmap(bitmapAltered); /* * 使用矩阵 */ Bitmap bitmapAltered = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());// 缺点是限定画布大小,处理后的图片可能被截断,可引入矩阵构造方法,动态设定画布大小 Canvas canvas = new Canvas(bitmapAltered);// bitmap提供了画布,只在此提供了大小尺寸,偏移后并未有背景显示出来, Paint paint = new Paint(); Matrix matrix = new Matrix(); // 1:缩放 // matrix.setValues(new float[] {//涉及线性代数的知识,能够翻翻相乘的基础知识 // 1,0,0,//算出x的值 // 0,1,0,//算出y的值 // 0,0,1//二维图用不到 // }); // 2:倾斜 // matrix.setValues(new float[] {//涉及线性代数的知识,能够翻翻相乘的基础知识 // 1,.5f,0,//算出x的值,x,y值相关 // 0,1,0,//算出y的值 // 0,0,1//二维图用不到 // }); // 3:旋转 // matrix.setRotate(45);//设置旋转角度,(0,0)点,顺时针旋转45度 // 4,缩放plus:使用Matrix类方法//须要修改画布宽度>1.5倍* 原始宽度 // matrix.setScale(1.5f, 1); // 5,平移 // matrix.setTranslate(10, 0); // 6,镜像 // eg1:x轴镜像 // matrix.setScale(-1, 1);//向左绘制,原始图片沿y轴对称 // matrix.postTranslate(bitmap.getWidth(), 0);//注意是post即后移动 // eg2:y轴镜像 matrix.setScale(1, -1);// 向上绘制,原始图片沿x轴对称,图像在第四象限 matrix.postTranslate(0, bitmap.getHeight());// 注意是post即后移动 //~optimize~由于指定画布大小bitmapAltered,因此处理后的图片可能被截断,能够经过矩阵动态改变bitmapAltered大小 //eg: matrix.setRotate(degrees, px, py) //bitmapAltered = Bitmap.createBitmap(source, x, y, width, height, m, filter);//显然矩阵影响其大小 // // 注:for more details :Wikipedia Transformation Matrix // http://en.wikipedia.org/wiki/Transformation_matrix canvas.drawBitmap(bitmap, matrix, paint);// 绘制的图片和以前的如出一辙 mImageAltered.setImageBitmap(bitmapAltered); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }