Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1814383
  • 博文数量: 438
  • 博客积分: 9799
  • 博客等级: 中将
  • 技术积分: 6092
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-25 17:25
文章分类

全部博文(438)

文章存档

2019年(1)

2013年(8)

2012年(429)

分类: 嵌入式

2012-03-25 21:18:02

还记得那个BeautyActivity吗?它对应的layout的xml里定义了一个ListView。要想在ListView里面加入item,只能通过代码(不能直接在xml里):


  1. String[] items = {"Item1", "Item2", "Item3"};
  2.         int itemResId = android.R.layout.simple_list_item_1; // TextView
  3.         
  4.         ArrayAdapter<String> adapter = new ArrayAdapter<String>(
  5.                 this, itemResId, items);
  6.         ListView lv = (ListView)findViewById(R.id.my_list_view);
  7.         lv.setAdapter(adapter);

android.R.layout.simple_list_item_1就是TextView的id。通过一个ArrayAdapter,ListView设置了自己的item列表。

如果我们不想使用默认的TextView显示ListView的一个item,而是要自己定义item的外观,怎么办?首先定义一个View的子类(SadItemView.java):
  1. package tommy.myandroid;

  2. import android.content.Context;
  3. import android.graphics.Canvas;
  4. import android.graphics.Paint;
  5. import android.util.AttributeSet;
  6. import android.widget.TextView;

  7. public class SadItemView extends TextView {
  8.     public SadItemView(Context context) {
  9.         super(context);
  10.     }
  11.     
  12.     public SadItemView(Context context, AttributeSet attrs) {
  13.         super(context, attrs);
  14.     }

  15.     public SadItemView(Context context, AttributeSet attrs, int defStyle) {
  16.         super(context, attrs, defStyle);
  17.     }
  18.     
  19.     @Override
  20.     protected void onDraw(Canvas canvas) {
  21.         super.onDraw(canvas); // draw text
  22.         Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
  23.         paint.setColor(0xffffffff);
  24.         canvas.drawLine(0, getMeasuredHeight() / 2,
  25.                 getMeasuredWidth(), getMeasuredHeight() / 2,
  26.                 paint);
  27.     }
  28. }

为了重用绘制文字的功能,SadItemView继承了TextView。类View有三个构造器,最好都定义好并调用父类的构造器。覆写onDraw可以自定义view的外观。

除了类文件,要在ListView里加入自己的item,还需要定义一个layout的xml(saditemview.xml):


  1. <?xml version="1.0" encoding="utf-8"?>
  2. <tommy.myandroid.SadItemView
  3.   xmlns:android=""
  4.   android:orientation="vertical"
  5.   android:layout_width="match_parent"
  6.   android:layout_height="match_parent" />

注意saditemview.xml里只有一个结点,而且结点名与刚刚定义的类名一样。定义好java类和layou后,就可以在ListView里添加我们自定义的item了:
  1. String[] items = {"Item1", "Item2", "Item3"};
  2. //int itemResId = android.R.layout.simple_list_item_1;
  3. int itemResId = R.layout.saditemview;
  4.         
  5. ArrayAdapter<String> adapter = new ArrayAdapter<String>(
  6.     this, itemResId, items);
  7. ListView lv = (ListView)findViewById(R.id.my_list_view);
  8. lv.setAdapter(adapter);

上面的代码使用了我们刚刚定义好的resource id,运行结果:


自定义一个全新的View


  1. class SimpleView extends View {
  2.     public SimpleView(Context context) {
  3.         super(context);
  4.     }
  5.     public SimpleView(Context context, AttributeSet attrs) {
  6.         super(context, attrs);
  7.     }
  8.     public SimpleView(Context context, AttributeSet attrs, int defStyle) {
  9.         super(context, attrs, defStyle);
  10.     }
  11.     
  12.     @Override
  13.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  14.         int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
  15.         int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
  16.         int measuredWidth = radius * 2;
  17.         if (widthSpecMode == MeasureSpec.AT_MOST) {
  18.             if (measuredWidth > widthSpecSize)
  19.                 measuredWidth = widthSpecSize;
  20.         } else if (widthSpecMode == MeasureSpec.EXACTLY){
  21.             measuredWidth = widthSpecSize;
  22.         }

  23.         int measuredHeight = radius * 2;
  24.         switch (MeasureSpec.getMode(heightMeasureSpec)) {
  25.         case MeasureSpec.AT_MOST:
  26.         case MeasureSpec.EXACTLY:
  27.         case MeasureSpec.UNSPECIFIED:
  28.             measuredHeight = MeasureSpec.getSize(heightMeasureSpec);
  29.             break;
  30.         }
  31.         
  32.         setMeasuredDimension(measuredWidth, measuredHeight);
  33.     }
  34.     
  35.     @Override
  36.     protected void onDraw(Canvas canvas) {
  37.         super.onDraw(canvas);
  38.         int width = getMeasuredWidth();
  39.         int height = getMeasuredHeight();
  40.         int r = Math.min(width, height) / 2;
  41.         Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
  42.         paint.setColor(color);
  43.         canvas.drawCircle(width/2, height/2, r, paint);
  44.     }

  45.     @Override
  46.     public boolean onTouchEvent(MotionEvent event) {
  47.         color &= 0x00ffffff;
  48.         if (color == 0x000000ff)
  49.             color = 0x00ff0000;
  50.         else
  51.             color >>= 8;
  52.         color |= 0xff000000; // alpha
  53.         invalidate();
  54.         return true;
  55.     }

  56.     private int radius = 5;
  57.     private int color = 0xffff0000;
  58. }

自定义的View主要需要覆写OnMeaure方法和OnDraw方法(画一个圈)。上例的类还通过响应了onTouchEvent,并改变圆的颜色。可以使用setContentView来设置这个View。运行结果:
阅读(1245) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~