Carlo
Carlo

Reputation: 835

ImageView in ListView with an ArrayList<String>

I'm new in Android, I want to create a list with the book's data. My list wants an image. I have to put in my ListView some images from url. I retrieve the String urlImages from my database.

This is my customAdapter:

 public class customAdapter extends ArrayAdapter<String>{

    Context mContext;
    ArrayList<String> user_name;
    ArrayList<String> book_title;
    ArrayList<String> book_author;
    ArrayList<String> book_price;
    ArrayList<String> book_cover;


    public customAdapter(Context context, ArrayList<String> user_name, ArrayList<String> book_title,
                         ArrayList<String> book_author, ArrayList<String> book_price, ArrayList<String> book_cover) {
        super(context, R.layout.row_list_books, book_title);
        // TODO Auto-generated constructor stub

        this.mContext = context;
        this.user_name = user_name;
        this.book_title = book_title;
        this.book_author = book_author;
        this.book_price = book_price;
        this.book_cover = book_cover;
    }

    public View getView(int position, View view, ViewGroup parent) {
        LayoutInflater inflater = LayoutInflater.from(mContext);
        View rowView = inflater.inflate(R.layout.row_list_books, null, true);

        TextView user = (TextView) rowView.findViewById(R.id.user_name_search);
        TextView title = (TextView) rowView.findViewById(R.id.bookTitle);
        TextView author = (TextView) rowView.findViewById(R.id.bookAuthor);
        TextView price = (TextView) rowView.findViewById(R.id.priceBook);
        ImageView bookImage = (ImageView) rowView.findViewById(R.id.coverBookSearch);

        user.setText(user_name.get(position));
        title.setText(book_title.get(position));
        author.setText(book_author.get(position));
        price.setText(book_price.get(position));

        ////   I don't know how I can do   ////
        bookImage.setImageBitmap(book_cover.get(position));
        ///////////////////////////////

        return rowView;

    }


}

this is my ListBooks activity:

Context mContext;
static final String KEY = "KEY", TAG_LOGIN = "TAG_LOGIN";
String key, getTagLogin;

String user_name;
DatabaseReference user;
DatabaseReference userBook = FirebaseDatabase.getInstance().getReference("Books").child("User's books");
ListView mListView;
ArrayList<String> mArrayUserName = new ArrayList<>();
ArrayList<String> mArrayTitle = new ArrayList<>();
ArrayList<String> mArrayAuthor = new ArrayList<>();
ArrayList<String> mArrayPrice = new ArrayList<>();
ArrayList<String> mArrayImage = new ArrayList<>();
customAdapter customAdapter;

@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_list_books);
    mContext = this;

    Intent intent = getIntent();
    key = intent.getStringExtra(KEY);
    getTagLogin = intent.getStringExtra(TAG_LOGIN);



    mListView = (ListView) findViewById(R.id.listView);

    customAdapter = new customAdapter(mContext, mArrayTitle, mArrayAuthor, mArrayUserName, mArrayPrice, mArrayImage);
    mListView.setAdapter(customAdapter);

    userBook.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                UserBook userBook = dataSnapshot.getValue(UserBook.class);
                user_name = userBook.user_name;
                String book_title = userBook.book_title;
                String book_author = userBook.book_author;
                String book_price = userBook.book_price;
                String book_cover = userBook.book_urlImage;


                mArrayUserName.add(user_name);
                mArrayTitle.add(book_title);
                mArrayAuthor.add(book_author);
                mArrayPrice.add(book_price);
                mArrayImage.add(book_cover);
                customAdapter.notifyDataSetChanged();

        }
        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {

        }

        @Override
        public void onChildMoved(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
}

}

Thank you in advance for your help.

Upvotes: 0

Views: 740

Answers (2)

Miguel Benitez
Miguel Benitez

Reputation: 2322

You could try using RecyclerView and Picasso to avoid having memory problems:

The RecyclerView widget is a more advanced and flexible version of ListView. This widget is a container for displaying large data sets that can be scrolled very efficiently by maintaining a limited number of views. Use the RecyclerViewwidget when you have data collections whose elements change at runtime based on user action or network events.

A layout manager positions item views inside a RecyclerView and determines when to reuse item views that are no longer visible to the user. To reuse (or recycle) a view, a layout manager may ask the adapter to replace the contents of the view with a different element from the dataset. Recycling views in this manner improves performance by avoiding the creation of unnecessary views or performing expensivefindViewById() lookups


Example:
Add this view to your layout:

<android.support.v7.widget.RecyclerView
    android:id="@+id/my_recycler_view"
    android:scrollbars="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

Once you have added a RecyclerView widget to your layout, obtain a handle to the object, connect it to a layout manager, and attach an adapter for the data to be displayed:

public class MyActivity extends Activity {
    private RecyclerView mRecyclerView;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_activity);
        mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
        // use this setting to improve performance if you know that changes
        // in content do not change the layout size of the RecyclerView
        mRecyclerView.setHasFixedSize(true);
        // use a linear layout manager
        mLayoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(mLayoutManager);
        // specify an adapter (see also next example)
        // Set your myDataSet with the url of your images.
        mAdapter = new MyAdapter(myDataset);
        mRecyclerView.setAdapter(mAdapter);
    }
    ...
}

Create an adapter to manage the recycler view:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    private String[] mDataset;

    // Provide a reference to the views for each data item
    // Complex data items may need more than one view per item, and
    // you provide access to all the views for a data item in a view holder
    public static class ViewHolder extends RecyclerView.ViewHolder {
        // each data item is just a string in this case
        public ViewHolder(ImageView v) {
            super(v);
            pictureView = v;
        }
    }

    // Provide a suitable constructor (depends on the kind of dataset)
    public MyAdapter(String[] myDataset) {
        mDataset = myDataset;
    }

    // Create new views (invoked by the layout manager)
    @Override
    public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                   int viewType) {
        // create a new view
        View v = LayoutInflater.from(parent.getContext())
                               .inflate(R.layout.my_image_view, parent, false);
        // set the view's size, margins, paddings and layout parameters
        ...
        ViewHolder vh = new ViewHolder(v);
        return vh;
    }

    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        //Resize your image
        options.inSampleSize = 4;
        BitmapFactory.decodeFile(objects[position].getAbsolutePath(), options);
         // - get element from your dataset at this position
        // - replace the contents of the view with that element
        Bitmap bmp = getBitmap(position);
        if (bmp != null) {
            pictureView.setImageBitmap(bmp);
        }

    }

    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return mDataset.length;
    }
}


info from:

http://developer.android.com/training/material/lists-cards.html
Also you can use external libraries which help you to manage big bitmaps, for example Picasso:
Add dependecies in build.gradle:

dependencies {
....
    compile 'com.squareup.picasso:picasso:2.3.2'
....
}

Change onBindViewHolder in your Adapter.ViewHolder:

  @Override
    public void onBindViewHolder(ViewHolder holder, int position) {

           String mURLPhoto = mDataset[position];
           Uri uri = Uri.fromFile(new File(mURLPhoto));

        if(!mURLPhoto.equals("")) {
            Picasso.with(parent.getContext())
                .load(uri).placeholder(R.mipmap.ic_logo)
                .resize(Constants.WIDTH_PHOTO_MINI, Constants.WIDTH_PHOTO_MINI).centerCrop()
                .into(pictureView);
        }
    }

Info from: http://square.github.io/picasso/

Hope helps!

Upvotes: 2

egoldx
egoldx

Reputation: 1520

Check Picasso. It will handle image downloading and caching for you.

Upvotes: 2

Related Questions