创建新视图的最佳方法与希望达到的目标有关:
<1>如果现有控件已经可以满足希望实现的基本功能,那么就只需要对现有控件的外观和行为进行修改或扩展即可
<2>可以通过组合多个视图来创建不可分割的、可重用的控件,从而使它可以综合使用多个相互关联的视图的功能。
<3>当需要一个全新的界面,而通过修改或者组合现有的控件不能实现这个目标的时候,就可以创建一个全新的控件。
<一> 修改现有控件实例分析
这里通过扩展了TextView 的 ToDoListItemView类,它包含一个重写onDraw 方法的stub ,以及调用了新的init方法stub的构造函数实现。
先上资源文件
res/values/colors.xml
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<color name="notepad_paper">#EEF8E0A0</color>
<color name="notepad_lines">#EF0000FF</color>
<color name="notepad_margin">#90FF0000</color>
<color name="notepad_text">#AA0000FF</color>
</resources>
res/values/dimens.xml
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<dimen name="notepad_margin">30dp</dimen>
</resources>
TextView 扩展类
public class ToDoListItemView extends TextView {
private Paint marginPaint;
private Paint linePaint;
private int paperColor;
private float margin;
public ToDoListItemView(Context context) {
super(context);
// TODO Auto-generated constructor stub
init();
}
public ToDoListItemView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
init();
}
public ToDoListItemView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
init();
}
private void init(){
Resources myResources = getResources();
//创建将在onDraw方法中使用的画刷
marginPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
marginPaint.setColor(myResources.getColor(R.color.notepad_margin));
linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
linePaint.setColor(myResources.getColor(R.color.notepad_lines));
//获取页面背景色和边缘宽度
paperColor = myResources.getColor(R.color.notepad_paper);
margin = myResources.getDimension(R.dimen.notepad_margin);
}
//要开始绘制页面 就需要重写onDraw 方法 并使用创建的Paint对象来绘制图像,一旦绘制了页面图像之后,就可以调用超类的onDraw方法 让它像往常一样绘制文本。
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
canvas.drawColor(paperColor);
//绘制边缘
canvas.drawLine(0, 0, 0, getMeasuredHeight(),linePaint);
canvas.drawLine(0, getMeasuredHeight(), getMeasuredWidth(), getMeasuredHeight(), linePaint);
//Draw margin
canvas.drawLine(margin, 0, margin, getMeasuredHeight(), marginPaint);
canvas.save();
canvas.translate(margin, 0);
//使用TextView 渲染文本
super.onDraw(canvas);
canvas.restore();
}
}
把扩展控件添加到一个新的布局文件中
res/layout/todolist_item.xml
<?xml version="1.0" encoding="utf-8"?>
<com.spreadtone.activitytest.ToDoListItemView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
android:scrollbars="vertical"
android:textColor="@color/notepad_text"
android:fadingEdge="vertical"
/>
最后一步是在ToDoListActivity 类的OnCreate 方法中改变传入ArrayAdapter的参数,使用R.layout.todolist_item布局的引用代替android.R.layout.simple-list_item_1布局的引用。
public class TodoListActivity extends Activity implements NewItemFragment.OnNewItemAddedListener {
private ArrayList<String> todoItems;
private ArrayAdapter<String> aa;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.todolist);
todoItems = new ArrayList<String>();
int resId=R.layout.todolist_item;
//aa=new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, todoItems);
aa=new ArrayAdapter<String>(this,resId, todoItems);
FragmentManager fm =getFragmentManager();
ToDoListFragment todoListFragment = (ToDoListFragment) fm.findFragmentById(R.id.ToDoListFragment);
todoListFragment.setListAdapter(aa);
}
@Override
public void onNewItemAdded(String newItem) {
// TODO Auto-generated method stub
todoItems.add(newItem);
aa.notifyDataSetChanged();
}
}
效果图如记事本