Рисование на холсте внутри элемента ListView - PullRequest
1 голос
/ 21 марта 2011

Я пытаюсь нарисовать на холсте внутри каждого элемента ListView.В настоящее время я использую следующий код, который выдает Force Close, как только я запускаю действие:

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>

1 Ответ

3 голосов
/ 21 марта 2011

Вам необходимо listRows = new ArrayList<Row>(); инициализировать список перед добавлением в него элементов.

В общем, попробуйте проверить вывод logcat в вашей перспективе отладки Eclipse или в ddms.В этом случае он сказал бы что-то вроде «нулевого указателя в onCreate», и вы бы сэкономили себе время.

Редактировать Я подозреваю, что это потому, что ваши Row просмотрыне знаю, насколько они должны быть большими.Вы можете попробовать переопределить 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 определит конструктор 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.

...