Gridview Adapter can't read from external storage, werid loop iterations - java

I have had a basic Gridview sample from Google's documentation, which worked perfectly.
I also have some code that provides result as ArrayList with Bitmaps of last created pictures in Android's external storage (Permissions in manifest are granted) and that code also worked just fine on other project.
When I merged that concepts into one simple app code isn't working at all, activity remains empty till app crashes. However I noticed something interesting: There's a for loop which has defined number of iterations by int capacity but in Logcat I can see that number of iterations in this loop surpassing declared int value, basically that's reason why app crashes (outOfBoundsException).
So i Have those 2 problems and sitting on that for couple of hours... here is my code:
MainActivity.java
package com.example.patryk.hellogridview;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GridView gridview = findViewById(R.id.gridview);
gridview.setAdapter(new ImageAdapter(this));
gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
Toast.makeText(MainActivity.this, "" + position,
Toast.LENGTH_SHORT).show();
}
});
}
PhotosReader.java
package com.example.patryk.hellogridview;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.provider.MediaStore;
import android.util.Log;
import java.util.ArrayList;
public class PhotosReader {
private int capacity = 5;
private ArrayList<Bitmap> photos = new ArrayList<Bitmap>(capacity);
public int getCapacity() {
return capacity;
}
public void setCapacity(int capacity) {
this.capacity = capacity;
}
public void setPhotos(ArrayList<Bitmap> photos) {
this.photos = photos;
}
public PhotosReader() {
}
public ArrayList<Bitmap> getPhotos(Context context) {
String[] projection = new String[]{
MediaStore.Images.ImageColumns._ID,
MediaStore.Images.ImageColumns.DATA,
MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME,
MediaStore.Images.ImageColumns.DATE_TAKEN,
MediaStore.Images.ImageColumns.MIME_TYPE
};
Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, null,
null, MediaStore.Images.ImageColumns.DATE_TAKEN + " DESC");
cursor.moveToFirst();
for(int i = 1; i<=capacity; i++){
photos.add(BitmapFactory.decodeFile(cursor.getString(1)));
cursor.moveToNext();
Log.d("photos.add", "iteration");
}
return photos;
}
public Bitmap getPhotosBitmap(ArrayList photos, int position){
Bitmap bm = (Bitmap) photos.get(position);
return bm;
}
}
ImageAdapter.java
package com.example.patryk.hellogridview;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
public class ImageAdapter extends BaseAdapter {
private Context mContext;
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
return 0;
}
public Object getItem(int position) {
return null;
}
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) {
ImageView imageView;
if (convertView == null) {
// if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
} else {
imageView = (ImageView) convertView;
}
PhotosReader PR = new PhotosReader();
imageView.setImageBitmap(PR.getPhotosBitmap(PR.getPhotos(mContext), position));
return imageView;
}
}

This function inside ImageAdapter should not return 0. It should return the number of images that you want to show in the grid so should return capacity in your case. GridView assumes that there are 0 things to show
public int getCount() {
return 0;
}
change this to
public int getCount() {
return capacity;
}
Actually the correct way to do this would be to pass the PhotoReader object from the ImageAdapter constructor using ImageAdapter(context,photoReader) and then use photoReader.getCapacity() in getCount() function

Related

Android GridView Place Half items on Left and Half on Right

Suppose we have 6 items, is there any possibility or way to place 3 items on left side of the row and 3 items on right side of the row in grid view and eventually we have a space in between them.
Actually I tried to give dynamic horizontal spacing after from the adapter but it didn't help me out. The picture is attached
package com.nxd.cap.Adapters;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import com.nxd.cap.R;
import java.util.ArrayList;
public class GalleryAdapter extends BaseAdapter {
Context context;
int[] images = new int[]{R.drawable.image1, R.drawable.image2, R.drawable.image3, R.drawable.image4,
R.drawable.image5, R.drawable.image6, R.drawable.image7, R.drawable.image8,
R.drawable.image1, R.drawable.image2};
public GalleryAdapter(Context context) {
this.context = context;
}
#Override
public int getCount() {
return images.length;
}
#Override
public Object getItem(int i) {
return images[i];
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
if (view == null){
LayoutInflater inflater = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.gallery_item, null);
ViewHolder viewHolder = new ViewHolder();
viewHolder.imageView = (ImageView)view.findViewById(R.id.imageView);
view.setTag(viewHolder);
}
ViewHolder viewHolder = (ViewHolder) view.getTag();
// Picasso.with(context).load(images[i]).into(viewHolder.image);
GridView gridView = (GridView)viewGroup;
if (i == images.length/2) {
gridView.setHorizontalSpacing(100);
}
viewHolder.imageView.setImageResource(images[i]);
return view;
}
static class ViewHolder {
ImageView imageView;
}
}
when you used gridView you can set number of column.if need only two column left and right set below code.
gridView.setNumColumns(2);

Saving dynamically added Views(pages) of Viewpager in SharedPreferences

Hi friends I am trying from long time to save dynamically added views of Viewpager in shardepreferences. So that when user next time open the app , his added pages or views should be there. But I have no success. I am trying to save the size of ArrayList in sharedpreferences and then trying to call regenerate the size of ArrayList next time when user open app. what I am doing is i am adding number of pages in pager with for loop that are equal to size of ArrayList. I dont know is this a right way or i am completely wrong. Please guide me someone through this. Thanks in advance. I am uploading the pic of my UI also enter image description here.I am pasting my code here. First below is code of my adapter.
import android.content.Context;
import android.content.SharedPreferences;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.ArrayList;
public class MainPagerAdapter extends PagerAdapter
{
private ArrayList<View> views = new ArrayList<View>();
SharedPreferences preferences;
Context context;
LayoutInflater inflater;
final static String PREF_COUNT="com.savesampledata";
final static String PREF_KEY="com.savesampledata.key";
final static String PREF_LIST="com.savesampledata.list";
final static String PREF_LIST_KEY="com.savesampledata.listkey";
int numberofview;
public MainPagerAdapter(Context c){
context=c;
}
#Override
public int getItemPosition (Object object)
{
int index = views.indexOf (object);
if (index == -1)
return POSITION_NONE;
else
return index;
}
#Override
public Object instantiateItem (ViewGroup container, int position)
{
Log.v("instantiate is called","now");
View v;
v = views.get(position);
if(v.getParent()!=null)
((ViewGroup)v.getParent()).removeView(v);
container.addView(v);
return v;
}
#Override
public void destroyItem (ViewGroup container, int position, Object object)
{
container.removeView (views.get (position));
}
#Override
public int getCount ()
{
Log.d("view list size",views.size()+"");
Log.d("numofViews before save",numberofview+"");
return views.size();
}
#Override
public boolean isViewFromObject (View view, Object object)
{
return view == object;
}
public int addView (View v)
{
return addView (v, views.size());
}
public int addView (View v, int position)
{
views.add (position, v);
return position;
}
public int removeView (ViewPager pager, View v)
{
return removeView (pager, views.indexOf (v));
}
public int removeView (ViewPager pager, int position)
{
if (numberofview > 1)
position = numberofview - 1;
if(position>0) {
pager.setAdapter(null);
views.remove(position);
pager.setAdapter(this);
}
return position;
}
public View getView (int position)
{
return views.get (position);
}
public void setCount(){
//storing size of views list
SharedPreferences preferences=context.getSharedPreferences(PREF_COUNT,Context.MODE_PRIVATE);
SharedPreferences.Editor editor=preferences.edit();
editor.putInt(PREF_KEY,views.size());
Log.d("shared stored val :",views.size()+"");
editor.apply();
}
public int getNumberOfView(){
//getting size of views list
SharedPreferences preferences=context.getSharedPreferences(PREF_COUNT, Context.MODE_PRIVATE);
numberofview=preferences.getInt(PREF_KEY,0);
return numberofview;
}
}
Code of my Activity:
import android.content.Context;
import android.content.SharedPreferences;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
public class ViewPagerActivity extends AppCompatActivity implements View.OnClickListener {
private ViewPager pager =null;
private MainPagerAdapter pageradapter=null;
Button addpagebtn,removebtn;
final static String PREF_COUNT="com.savesampledata";
final static String PREF_KEY="com.savesampledata.key";
int numberofview;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_pager_activity);
addpagebtn=(Button)findViewById(R.id.addbtn) ;
removebtn=(Button)findViewById(R.id.removeButton);
removebtn.setOnClickListener(this);
addpagebtn.setOnClickListener(this);
pageradapter= new MainPagerAdapter(this);
pager=(ViewPager)findViewById(R.id.view_pager);
pager.setAdapter(pageradapter);
pager.setOffscreenPageLimit(3);
numberofview=pageradapter.getNumberOfView();//here i am getting the value
Log.d("value after saving",pageradapter.getNumberOfView()+"");
LayoutInflater inflater=getLayoutInflater();
FrameLayout v0=(FrameLayout)inflater.inflate(R.layout.sample_layout_page,null);
pageradapter.addView(v0,0);
pageradapter.notifyDataSetChanged();
if(numberofview>1) {
Log.d("ManyView","added");
for (int i = 1; i <= numberofview; i++) {
pageradapter.addView(v0,i);
pageradapter.notifyDataSetChanged();
}
}
}
public void addView(View newpage){
int pageIndex=pageradapter.addView(newpage);
Log.d("page added at",pageIndex+"");
pageradapter.notifyDataSetChanged();
pageradapter.setCount();
pager.setCurrentItem(pageIndex,true);
}
public void removeView(View defunctPage){
int pageindex=pageradapter.removeView(pager,defunctPage);
Log.d("page removed at",pageindex+"");
pageradapter.notifyDataSetChanged();
pageradapter.setCount();
if(pageindex==pageradapter.getCount())
pageindex--;
pager.setCurrentItem(pageindex);
}
public View getCurrentPage(){
return pageradapter.getView(pager.getCurrentItem());
}
public void setCurrentPage(View pageToShow){
pager.setCurrentItem(pageradapter.getItemPosition(pageToShow),true);
}
#Override
public void onClick(View v) {
if(v.getId()==R.id.addbtn) {
LayoutInflater inflater=getLayoutInflater();
FrameLayout v0=(FrameLayout)inflater.inflate(R.layout.sample_layout_page,null);
addView(v0);
pageradapter.setCount();
}
if(v.getId()==R.id.removeButton){
View v1=getCurrentPage();
removeView(v1);
pageradapter.setCount();
}
}
#Override
protected void onStop() {
//here I am storing value
super.onStop();
pageradapter.setCount();
}
}

In Android, how to achieve snap effect on a listview while respecting acceleration caused by fling?

For demonstration, I have a ListView displaying a list of numbers. I would like to achieve the effect that when the user scrolls the ListView and the scrolling ends, it will only stop at certain positions so that the first visible item is always shown completely. I've attached my attempted code below. It works when users drag to scroll the ListView. But when there's fling, the normal acceleration is interrupted, causing an unnatural stop. My question is, how can I take acceleration caused by fling into account while achieving the same effect?
package com.example.snaptest;
import android.content.Context;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
public class MainActivity extends ActionBarActivity {
private static class TestListViewAdapter extends BaseAdapter {
private Context mContext;
public TestListViewAdapter(Context context) {
mContext = context;
}
#Override
public int getCount() {
return 100;
}
#Override
public Object getItem(int position) {
return Integer.toString(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView textView = new TextView(mContext);
textView.setText(Integer.toString(position));
AbsListView.LayoutParams params = new AbsListView.LayoutParams(ViewGroup.LayoutParams
.MATCH_PARENT, 180);
textView.setLayoutParams(params);
return textView;
}
}
private static class TestListView extends ListView {
public TestListView(Context context) {
super(context);
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_CANCEL) {
View itemView = getChildAt(0);
int top = Math.abs(itemView.getTop()); // top is a negative value
int bottom = Math.abs(itemView.getBottom());
if (top >= bottom){
smoothScrollToPositionFromTop
(getFirstVisiblePosition() + 1, 0);
} else {
smoothScrollToPositionFromTop
(getFirstVisiblePosition(), 0);
}
}
return super.onTouchEvent(ev);
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TestListView listView = new TestListView(this);
listView.setAdapter(new TestListViewAdapter(this));
setContentView(listView);
}
}
I would try with an OnScrollListener rather than extending ListView.
Something like this:
listView.setOnScrollListener(new AbsListView.OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == AbsListView.SCROLL_STATE_IDLE) {
// snap the listview according to the top/bottom items' visibility
}
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
});

Android prompting to save image or set wallpaper from gridview

I would like the user to get the option once the chosen image is clicked to set the image as their wallpaper or to save it to their SD card.
This is my first time doing this so I need some guidance. I have looked at other questions similar to this one but everyone uses different methods to the one I have done to set up displaying the images.
Thanks in advance, here's the code:
AdapterView for Displayimagesin:
package com.question;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
public class AdapterViewADV extends BaseAdapter {
private Context mContext;
public Integer[] mThumbIds = {
R.drawable.Image1,
R.drawable.Image2,
R.drawable.Image3,
R.drawable.Image4,
R.drawable.Image5,
R.drawable.Image6
};
public AdapterViewADV(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 = null;
if(convertView == null){
imageView = new ImageView(mContext);imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new GridView.LayoutParams(NO_SELECTION, NO_SELECTION));
convertView = imageView;
}else{
imageView = (ImageView)convertView;
}
imageView.setImageResource(mThumbIds[position]);
return convertView;
}
}
Class displaying images in:
package com.question;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;
import android.widget.Toast;
public class Displayimagesin extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_battlefield4);
GridView gridView = (GridView) findViewById(R.id.grid_view);
// Instance of ImageAdapter Class
gridView.setAdapter(new AdapterViewADV(this));
gridView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
Toast.makeText(Displayimagesin.this, "Wallpaper set",
Toast.LENGTH_SHORT).show();
}
});
}
}
set wallpaper by calling WallpaperManager .
get a reference to your image to Bitmap.
something like this
WallpaperManager wm=WallpaperManager.getInstance(this);
wm.setBitmap(bitmap);
and in manifest file add permission
android.permission.SET_WALLPAPER
hope it helps.
Try to use WallpaperManager to set wallpaper
WallpaperManager myWallpaperManager=WallpaperManager.getInstance(getApplicationContext());
myWallpaperManager.setResource(mThumbIds[curruntPosition]);

OutOfMemoryException while scroll many time

I got a problem in gridview scroll. I have make one custom gridview and insert widget in raw file and inflate them through view. I got proper result and proper data and everything is gone well but when I scroll gridview 3-4 times up down speedy it raises an OutOfMemoryException.
This app contain list of installed app list and icon
Here is my custome adapter's code:
package com.AppFavorits;
import java.util.ArrayList;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.AppFavorits.ImageLoad.ImageLoader;
public class GridViewAdapter extends BaseAdapter {
private Context activit;
LayoutInflater inflator;
public RelativeLayout imgvGridItem;
public TextView txtGridItemlabel;
public CheckBox chkbxGridItem;
ArrayList<PInfo> lstpinfo = new ArrayList<PInfo>();
public ImageLoader imageLoader;
public GridViewAdapter(Context m1, ArrayList<PInfo> lstpinfo) {
activit = m1;
inflator = LayoutInflater.from(m1);
this.lstpinfo = lstpinfo;
imageLoader=new ImageLoader(m1.getApplicationContext());
}
public static class ViewHolder {
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder view;
// LayoutInflater inflator = activit.getLayoutInflater();
view = new ViewHolder();
convertView = inflator.inflate(R.layout.gridviewrow, null);
imgvGridItem = (RelativeLayout) convertView
.findViewById(R.id.rlGreidItemicon);
txtGridItemlabel = (TextView) convertView
.findViewById(R.id.txtGridItemlabel);
chkbxGridItem = (CheckBox) convertView
.findViewWithTag(R.id.chkbxGridItem);
if ((lstpinfo.get(position).appname.toString()) != null){
Drawable d = lstpinfo.get(position).icon;
//new ImageLoad().execute();
imgvGridItem.addView(getimageviewimage(lstpinfo.get(position).icon));
txtGridItemlabel.setText(lstpinfo.get(position).appname.toString());
// convertView.setTag(view);
}
return convertView;
}
#Override
public int getCount() {
return lstpinfo.size();
}
#Override
public Object getItem(int position) {
return lstpinfo.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public RelativeLayout getimageviewimage(Drawable d) {
RelativeLayout seprator = new RelativeLayout(activit);
seprator.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
seprator.setGravity(Gravity.LEFT | Gravity.CENTER);
ImageView imgmap = new ImageView(activit);
imgmap.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
// imgmap.setBackgroundResource(R.drawable.a13);
Bitmap bitmap = ((BitmapDrawable)d).getBitmap();
imageLoader.DisplayImage(bitmap, imgmap);
//imgmap.setImageBitmap(bitmap);
seprator.setPadding(5, 5, 15, 5);
seprator.addView(imgmap);
return seprator;
}
private class ImageLoad extends AsyncTask<Void, Void, Void> {
// private final ProgressDialog dialog = new ProgressDialog(tranning.this);
protected void onPreExecute() {
// this.dialog.setMessage("Please Wait...");
// this.dialog.show();
// put your code which preload with processDialog
}
#Override
protected Void doInBackground(Void... arg0) {
// put your code here
return null;
}
#Override
protected void onPostExecute(final Void unused) {
/*if (this.dialog.isShowing()) {
this.dialog.dismiss();
} */
}
}
}
I think there are something wrong with getview.
In getView() you are not reusing convertView, but always inflating new one with inflator. This requires more memory and makes your code slower. Also, check that you are not leaking images with imageLoader.
out of memory usually means that there is not enough memory to load the file. try closing everything else (or atleast a few other apps) and trying again.
Download code From Following link and use gridview instead of listview
Lazy Loading Example

Categories

Resources