If you check out this answer.
Lazy load of images in ListView
Fedor has provided a tutorial on how to lazy load with image view.
But he said it can be used with Gallery with minor modifications.
How do i go about doing this with minor modifications?
Ive Tried this so far.
This is the BaseAdapter
public class LazyAdapter extends BaseAdapter {
private Activity activity;
private String[] data;
private static LayoutInflater inflater=null;
public ImageLoader imageLoader;
public LazyAdapter(Activity a, String[] d) {
activity = a;
data=d;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader=new ImageLoader(activity.getApplicationContext());
}
public int getCount() {
return data.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
if(convertView==null)
vi = inflater.inflate(R.layout.item, null);
TextView text=(TextView)vi.findViewById(R.id.text);;
ImageView image=new ImageView(this.activity);
text.setText("item "+position);
imageLoader.DisplayImage(data[position], activity, image);
return vi;
}
}
And then in my activity i do this..
LazyAdapter adapter=new LazyAdapter(MainMenu.this, myRemoteImages);
((Gallery) findViewById(R.id.gallery))
.setAdapter(adapter);
It doesnt seem to be working though.
Nothing is showing up
Here is something that I managed to work out. After implementing Fedor's code in a GridView, you must be aware that in the ImageLoader class file there is a class named decodeFile(). In that class Fedor's code automatically resizez the image so that it can become a small thumbnail. You have just to comment the "rescaling" part and your image will appear in full in the GalleryView.
Related
My project is a tuition management book in this I list all students with their photos, names, IDs, classes in Activity by using a custom listView it runs well but when adding more student it showing lag in listview scrolling. using the below adapter I am facing scroll lag in listView. I reduce the size of the image(under 500kb)which store in the SQLite database but still it's not working smoothly. **
Adapter code
public class MyListAdapter extends BaseAdapter {
private Context context;
private int layout;
private ArrayList<slmodel> recordlist;
public MyListAdapter(Activity context, int layout, ArrayList<slmodel> recordlist) {
this.context = context;
this.layout= layout;
this.recordlist = recordlist;
}
#Override
public int getCount() {
return recordlist.size();
}
#Override
public slmodel getItem(int position) {
return recordlist.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
private class ViewHolder{
ImageView imageView;
TextView name,id, sclass;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row=convertView;
ViewHolder holder=new ViewHolder();
if(row==null)
{
LayoutInflater inflater=(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row=inflater.inflate(layout,null);
holder.name=row.findViewById(R.id.bname);
holder.id=row.findViewById(R.id.sid);
holder.sclass =row.findViewById(R.id.scourse);
holder.imageView=row.findViewById(R.id.imageView);
row.setTag(holder);
}
else{
holder=(ViewHolder)row.getTag();
}
slmodel model=recordlist.get(position);
holder.name.setText(model.getName());
holder.id.setText(model.getId().toString());
holder.sclass.setText(model.getsclass());
byte[] recordimgae=model.getImgae();
Bitmap bitmap= BitmapFactory.decodeByteArray(recordimgae,0,recordimgae.length);
holder.imageView.setImageBitmap(bitmap);
return row;
}
}
Welcome to SO, and congratulations on posting your first question.
use image loading libraries like Picasso or Glide
with these libraries, you can:
resize your image
use caches to decrease loading time
handle background thread automatically for loading and converting bitmaps.
sample for Glide:
Glide.with(context)
.load(recordImage)
.asBitmap()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(holder.imageView);
While using a ViewPager i noticed that it wouldn't respond very quickly, meaning that it slows down when switchting through fragments, kind of in a laggy way.
Does anyone know how this code could be causing the issue?
public class List_adapter : BaseAdapter<Element>
{
public List<Element> _list;
FragmentOne _context;
public List_adapter(FragmentOne context, List<Element> list)
{
super(context, list);
_list = list;
_context = context;
}
#Override
public int getCount()
{
return _list.size();
}
#Override
public Object getItem(int position)
{
return _list.get(position);
}
#Override
public long getItemId(int position)
{
return getItem(position).hashCode();
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
LayoutInflater inflater = (LayoutInflater)getActivity().getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.row, parent, false);
Element item = getItem(position);
TextView lbl = (TextView)view.findViewById(R.id.label);
TextView prop = (TextView)view.findViewById(R.id.Prop);
lbl.setText(item.getlabel());
prop.setText(item.getprop());
return view;
}
}
Use ViewHolder pattern for smooth list scrolling
Implement Offscreen page limit for initialising a view before showing it inside ViewPager
I'm reading in places that it's necessary to have a main method in each class like this:
public static void main(String args [ ]) { }
However, none of my classes in my current project contain such a method, and so far my app experiences no issues...here's one of my classes for reference.
public class GridAdapter extends BaseAdapter {
private final String[] classes = {"Database"}; // Sets the labels for each button
private Context mContext;
public GridAdapter(Context c) {
mContext = c;
}
public int getCount() { //autogenerated tab, returns length of an array.
return mThumbIds.length;
}
// The position an item is in in an array.
public Object getItem(int position) {
return mThumbIds[position];
}
// Gets the ID of each item in the array.
public long getItemId(int position) {
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridView;
if (convertView == null) { // if it's not recycled, initialize some attributes
gridView = new View(mContext);
gridView = inflater.inflate(R.layout.gridset, null);
TextView textView = (TextView) gridView
.findViewById(R.id.label);
textView.setText(classes[position]);
ImageView imageView = (ImageView) gridView
.findViewById(R.id.img);
imageView.setImageResource(mThumbIds[position]);
} else {
gridView = convertView;
}
return gridView;
}
// references to our images
private Integer[] mThumbIds = {
R.drawable.img};
}
Is it because I'm extending something (in this case BaseAdapter)? Right now the classes that are currently complete and actually function have an extension, So I am wondering if my WIP classes that don't will need a main() method.
Your reference reads "in at least one class" and pertains to a standalone Java SE program.
In Android you, however, do not need main at all. Your Activities will be brought to life by Android OS calling callbacks into your Activities such as onCreate, onPause etc...
I am trying to make a gridview on LayoutInflater, when i test my app, it always crashes.
here is my code :
public class Level1 extends Fragment {
public static Fragment newInstance(Context context) {
Level1 f = new Level1();
return f;
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.grid_layout, null);
GridView gridView = (GridView) root.findViewById(R.id.grid_view);
gridView.setAdapter(new ImageAdapter(root.getContext()));
}
I think, my problem is in "setAdapter". I can't use context "xxx.this". I've try to change setAdapter context with "getContext" and "getApplicationContext" but it still crashes.
when i delete "setAdapter" my app working but without gridView.
My ImageAdapter is look like this :
public class ImageAdapter extends BaseAdapter {
private Context mContext;
public Integer[] mThumbIds = {
R.drawable.pic_1, R.drawable.pic_2,
R.drawable.pic_3, R.drawable.pic_4,
R.drawable.pic_5, R.drawable.pic_6,
R.drawable.pic_7, R.drawable.pic_8,
R.drawable.pic_9, R.drawable.pic_10,
R.drawable.pic_11, R.drawable.pic_12,
R.drawable.pic_13, R.drawable.pic_14,
R.drawable.pic_15
};
// Constructor
public ImageAdapter(Context c){
mContext = c;
}
#Override
public int getCount() {
return mThumbIds.length;
}
#Override
public Object getItem(int position) {
return mThumbIds[position];
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView = new ImageView(mContext);
imageView.setImageResource(mThumbIds[position]);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new GridView.LayoutParams(70, 70));
return imageView;
}
}
Please help me..
Please set a breakpoint on this line GridView gridView = (GridView) root.findViewById(R.id.grid_view); and start debugging your app (in eclipse it's the button on the left side of the button you usually use to start your application). When the breakpoint is reached please step over one step and see if gridView is null. For me this looks like the most reasonable source of your error. But without a detailled error message it's hard to say, so please update your post.
if you are getting OUTOFMEMORY exception its generally because you are using large size images. you will have to sample it down. and in fragment you have to use getactivity() for context.
What I am trying to do is access an ArrayList that is in my main activity from a customer adapter for a listview.
I have a listview that I am making clickable, which I have done within the customer adapter(where the onclick resides). When the user clicks it they will enter a caption(text) which will update an arraylist(string) in the main activity.
I have read a few other questions about this topic but I'm lost on how to make this work.
I didn't see the need to post a code snippet because it's just a basic arraylist(string) and a custom adapter for a listview. If code is needed I can post though. Thanks!
Here part of the adapter code:
public class PhotoAdapter extends ArrayAdapter<Photo> {
private final ArrayList<Photo> objects;
public PhotoAdapter(Context context, int textViewResourceId,
ArrayList<Photo> objects) {
super(context, textViewResourceId, objects);
this.objects = objects;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final Photo i = objects.get(position);
View v = convertView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.listview_row, null);
v.setClickable(true);
v.setFocusable(true);
}
Here is come code from the main activity
public ArrayList<Photo> m_photos = new ArrayList<Photo>();
public ArrayList<String> m_photo_captions = new ArrayList<String>();
private PhotoAdapter m_adapter;
this.list1 = (ListView) findViewById(R.id.lstPhotos);
m_adapter = new PhotoAdapter(this, R.layout.listview_row, m_photos);
LayoutInflater infalter = getLayoutInflater();
list1.setAdapter(m_adapter);
if (Intent.ACTION_SEND_MULTIPLE.equals(action)
&& intentGallery.hasExtra(Intent.EXTRA_STREAM)) {
ArrayList<Parcelable> list = intentGallery
.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
for (Parcelable p : list) {
Uri uri = (Uri) p;
imagePath = getPath(uri);
m_photos.add(new Photo(imagePath, ""));
m_photo_locations.add(imagePath);
m_photo_captions.add("");
m_adapter.notifyDataSetChanged();
}
}
onclick listener
list1.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
// Do whatever you want with m_photo_captions here
Log.v("listview", "listview item clicked");
appErrorAlert("test", "test");
}
});
You can define the ArrayList you want to access as a global instance variable, that way you can access it from inside your custom adapter.
It'll also be helpful if you provided a code snippet for your problem.
Now that you have posted your code, I would suggest a different approach than Mohamed A. Karim's.
You are trying to set a simple OnClickListener on the entire row in your Adapter but access members of your Activity. Why not just set an OnItemClickListener in your ListView which already has access to the List that you want?
list1.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
// Do whatever you want with m_photo_captions here
}
});
Next remove everything that will intercept the touch event before it reaches your ListView. You can also make your getView() a little smaller and faster, like this:
public class PhotoAdapter extends ArrayAdapter<Photo> {
LayoutInflater mInflater;
public PhotoAdapter(Context context, int textViewResourceId,
ArrayList<Photo> objects) {
super(context, textViewResourceId, objects);
mInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final Photo i = get(position);
View v = convertView;
if (v == null) {
v = mInflater.inflate(R.layout.listview_row, null);
// Initialize your ViewHolder here!
}
// Update your TextViews, ImageViews, etc here
...
}
}
Hope that helps!