我正在尝试在ListView的每个元素内绘制一个Canvas。目前我正在使用以下代码,一旦我启动活动就会强制关闭:
Main.java
public class Main extends Activity
{
private ListView listView;
private List<Row> listRows;
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.year);
//Added initialisation from answers
listRows = new ArrayList<Row>();
//Add some generic rows to the list for test purposes
for (int i=0; i<4; i++) {
listRows.add(new Row(this));
}
listView = (ListView)findViewById(R.id.ListView1);
listView.setAdapter(new RowAdapter(this, listRows));
}
}
RowAdapter.java
public class RowAdapter extends BaseAdapter
{
private List<Row> elements;
private Context context;
public RowAdapter(Context c, List<Row> rows) {
this.elements = rows;
this.context = c;
}
@Override
public int getCount() {
return elements.size();
}
@Override
public Object getItem(int position) {
return elements.get(position);
}
@Override
public long getItemId(int id) {
return id;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return elements.get(position);
}
}
Row.java
public class Row extends View
{
public Row(Context context) {
super(context);
}
@Override
public void onDraw(Canvas canvas) {
//Draw simple string as an example
Paint paint = new Paint();
paint.setColor(Color.WHITE);
canvas.drawText("Text here...", 0, 0, paint);
}
}
我意识到我的方法可能有很多问题,所以如果有人能指出我正确的方向,我将不胜感激。
提前感谢您的帮助。
编辑: ListView现在加载但不显示任何元素。我正在使用下面显示的main.xml文件。
main.xml中
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout
android:id="@+id/LinearLayout01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<ListView
android:id="@+id/ListView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</ListView>
</LinearLayout>
答案 0 :(得分:3)
在向其中添加元素之前,您需要listRows = new ArrayList<Row>();
初始化列表。
通常,尝试在Eclipse调试透视图或ddms中检查logcat的输出。在这种情况下,它会说“onCreate中的空指针”的效果,你可以节省一些时间。
修改我怀疑这是因为您的行视图不知道应该有多大。您可以尝试使用简单方法覆盖onMeasure
作为完整性检查:
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(100, 100);
}
通过更好地分解代码可以减轻执行此操作的需要。适配器的基础数据并不意味着直接触摸视图;通常,视图是在getView
。
例如,您可能在res/layout/row.xml
:
<?xml version="1.0" encoding="utf-8"?>
<com.example.HelloCanvas
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
... other attributes like background color ...
/>
通过这种方式,您可以在自定义视图中设置xml属性,如果您在多个位置使用它,这很不错。
然后HelloCanvas将定义布局inflater使用的HelloCanvas(Context, AttributeSet)
构造函数:
public HelloCanvas(Context context, AttributeSet attrs) {
super(context, attrs);
}
最后,您的getView
方法会让row.xml
:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
HelloCanvas hello = (HelloCanvas) convertView;
if (hello == null) {
// inflate a new view
hello = (HelloCanvas)
LayoutInflater.from(getContext()).inflate(R.layout.row, parent, false);
}
hello.setHelloString(getItem(position));
return hello;
}
这样,如果不需要,您就不会生成新视图,并且ArrayAdapter的基础数据类型(消除了一些超出的代码)可以是String。