Вопрос

I try to load ListView items with a custom CursorLoader into a list. The problem is, if I scroll to the bottom and up again Android adds multiple new images to every list item. My question is, how to prevent Android to load more images into the list.
Column 1 should always have only one image, column 2 two images...

Main.java

public class Main extends FragmentActivity
    implements LoaderManager.LoaderCallbacks<Cursor> {

private Context mCtx       = null;
private MyAdapter mAdapter = null;

private final static String COLUMN_A = "a";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mCtx     = this;
    mAdapter = new MyAdapter(mCtx);

    ((ListView) findViewById(R.id.listview)).setAdapter(mAdapter);
    getSupportLoaderManager().initLoader(0, null, this);
}


@Override
public Loader<Cursor> onCreateLoader(int loader_id, Bundle bundle) {

    return new MyCursorLoader(mCtx) {

        @Override
        public Cursor loadInBackground() {
            MatrixCursor m = new MatrixCursor(new String[]{"_id", COLUMN_A});
            m.addRow(new String[]{"1", "Column 1"});
            m.addRow(new String[]{"2", "Column 2"});
            m.addRow(new String[]{"3", "Column 3"});
            m.addRow(new String[]{"4", "Column 4"});
            m.addRow(new String[]{"5", "Column 5"});
            return m;
        }
    };
}

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor c) {
    mAdapter.changeCursor(c);
}

@Override
public void onLoaderReset(Loader<Cursor> loader) {
    mAdapter.changeCursor(null);
}


private class MyAdapter extends CursorAdapter {
    private final LayoutInflater mInflater;

    public MyAdapter(final Context ctx) {
        super(ctx, null, 0);
        mInflater = LayoutInflater.from(ctx);
    }

    @Override
    public View newView(Context ctx, Cursor c, ViewGroup parent) {
        return mInflater.inflate(R.layout.item, parent, false);
    }

    @Override
    public void bindView(final View v, final Context ctx, final Cursor c) {
        LinearLayout parent = (LinearLayout) v;
        final int position = c.getPosition();

        Log.i("MyAdapter", "Cursor position: "+ position
                + "\tImages: "+ (parent.getChildCount() -1));

        ((TextView) v.findViewById(R.id.content))
            .setText(c.getString(c.getColumnIndex(COLUMN_A)));


        LinearLayout ll = new LinearLayout(ctx);
        ll.setOrientation(LinearLayout.VERTICAL);

        for (int i=0; i<(position+1); i++) {
            SystemClock.sleep(i * 100);
            ImageView img = new ImageView(ctx);
            img.setImageResource(R.drawable.ic_launcher);
            ll.addView(img);
        }

        parent.addView(ll);
    }
}


private abstract class MyCursorLoader extends CursorLoader {

    public MyCursorLoader(Context ctx) {
        super(ctx);
    }

    @Override
    public abstract Cursor loadInBackground();
}

}

activity_main.xml

<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".Main" >

    <ListView android:id="@+id/listview"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    </ListView>

</RelativeLayout>

item.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" >

    <TextView android:id="@+id/content"
    android:layout_width="match_parent"
    android:layout_height="30dip"
    android:text="---"
    />


</LinearLayout>


↓ after trying Diogo Bento suggestion on a Galaxy S1: enter image description here

Это было полезно?

Решение

that is not an efficient solution, but you can remove the LinearLayout. an efficient solution is to check if the LinearLayout has the number of childs different to the position and add or remove the images to get the number of images that you want.

**parent.removeViewAt(1);**
LinearLayout ll = new LinearLayout(ctx);
ll.setOrientation(LinearLayout.VERTICAL);

 for (int i=0; i<(position+1); i++) {
        SystemClock.sleep(i * 100);
        ImageView img = new ImageView(ctx);
        img.setImageResource(R.drawable.ic_launcher);
        ll.addView(img);
 }
parent.addView(ll);

Другие советы

try this:

public void bindView(final View v, final Context ctx, final Cursor c) {
LinearLayout parent = (LinearLayout) v;
final int position = c.getPosition();

Log.i("MyAdapter", "Cursor position: "+ position
        + "\tImages: "+ (parent.getChildCount() -1));

((TextView) v.findViewById(R.id.content))
    .setText(c.getString(c.getColumnIndex(COLUMN_A)));
//use a linear layout defined in the item.xml instead of dynamically create one
LinearLayout ll = (LinearLayout)v.findViewById(R.id.linearlayout);
for (int i=0; i<(position+1); i++) {
    SystemClock.sleep(i * 100);
    ImageView img = new ImageView(ctx);
    img.setImageResource(R.drawable.ic_launcher);
    //assign an id to the image to add
    int id = i+10000;
    img.setId(id);
    //check if the image has been already added.
    if(ll.findViewById(id) == null){
        ll.addView(img);
    }
}

}

item.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" >

    <TextView android:id="@+id/content"
    android:layout_width="match_parent"
    android:layout_height="30dip"
    android:text="---"/>
    <LinearLayout 
        android:id="@+id/linearlayout"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </LinearLayout>
</LinearLayout>

EDIT:

you can of course skip the creation of the image and the sleep on next scrolling if you slightly change the for loop like this:

    for (int i=0; i<(position+1); i++) {
        int id = i+10000;
    //check if the image has been already added.
    if(ll.findViewById(id) == null){ 
        SystemClock.sleep(i * 100);
        ImageView img = new ImageView(ctx);
        img.setImageResource(R.drawable.ic_launcher);
        //assign an id to the image to add
        img.setId(id);
        ll.addView(img);
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top