Android volley gridview onclick item index doesnt start with 0 - java

I am using a custom gridview adapter to show images with volley singleton. The gridview showing the images are fine, its just that when I click the FIRST image it crashes instantly.
I have tried using URLS[i-6] but it doesnt return the right thing. There are 6 images, somehow the index of the first image is 6 thus causing the out of bound exception. I tried changing bits here and there that might cause the index starting at 6 but no result at all..
The error:
java.lang.ArrayIndexOutOfBoundsException: length=6; index=6
at com.example.user.assignmentfourtwo.MainActivity$1$1.onItemClick(MainActivity.java:80)
Which is this line:
Toast.makeText(MainActivity.this, URLS[i].toString(), Toast.LENGTH_LONG).show();
MainActivity.java:
public class MainActivity extends AppCompatActivity {
private final int THUMBNAIL_SIZE = 250;
private final String KEY = "IMAGE";
ArrayList<Bitmap> bitmaps = new ArrayList<Bitmap>();
private static final String URLS[] = {
"http://10.0.2.2/Android%20A4_1/germany.png",
"http://10.0.2.2/Android%20A4_1/indonesia.png",
"http://10.0.2.2/Android%20A4_1/japan.png",
"http://10.0.2.2/Android%20A4_1/sarawak.png",
"http://10.0.2.2/Android%20A4_1/singapore.png",
"http://10.0.2.2/Android%20A4_1/switzerland.png",
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
for(int i = 0; i<URLS.length; i++) {
LoadingImages(URLS[i]);
}
}
private void LoadingImages(String url) {
ImageLoader imageLoader = MySingleton.getInstance(getApplicationContext()).getImageLoader();
imageLoader.get(url, new ImageLoader.ImageListener() {
#Override
public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) {
Bitmap image = response.getBitmap();
Bitmap thumbnail = ThumbnailUtils.extractThumbnail(image, THUMBNAIL_SIZE, THUMBNAIL_SIZE);
bitmaps.add(thumbnail);
GridView gridView = (GridView)findViewById(R.id.grid_layout);
final ImageAdapter imageAdapter = new ImageAdapter(MainActivity.this, bitmaps);
gridView.setAdapter(imageAdapter);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Toast.makeText(MainActivity.this, URLS[i].toString(), Toast.LENGTH_LONG).show();
// Intent intent = new Intent(getApplicationContext(), Main2Activity.class);
// intent.putExtra(KEY, URLS[i]);
// startActivity(intent);
}
});
}
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Do you even error?", error.getMessage());
}
});
}
}
MySingleton.java:
public class MySingleton {
private static MySingleton instance;
private RequestQueue requestQueue;
private ImageLoader imageLoader;
private static Context context;
private MySingleton(Context context){
this.context = context;
requestQueue = Volley.newRequestQueue(context);
imageLoader = new ImageLoader(requestQueue, new ImageLoader.ImageCache() {
private final LruCache<String, Bitmap> cache = new LruCache<>(6);
#Override
public Bitmap getBitmap(String url) {
Bitmap bmp = cache.get(url);
if (bmp == null) {
System.out.println("Not in cache");
} else {
System.out.println("In cache");
}
return bmp;
}
#Override
public void putBitmap(String url, Bitmap bitmap) {
System.out.println("Put in cache");
cache.put(url, bitmap);
}
});
}
public static synchronized MySingleton getInstance(Context context) {
if (instance == null) {
instance = new MySingleton(context);
}
return instance;
}
public ImageLoader getImageLoader() {
return imageLoader;
}
}
ImageAdapter.java:
public class ImageAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<Bitmap> bitmaps;
private final String KEY = "IMAGE";
public ImageAdapter(Context context, ArrayList<Bitmap> bitmaps) {
this.mContext = context;
this.bitmaps = bitmaps;
}
#Override
public int getCount() {
return bitmaps.size();
}
#Override
public Object getItem(int i) {
return bitmaps.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
if (view == null) {
final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
view = layoutInflater.inflate(R.layout.griditems, null);
MyViewHolder myViewHolder = new MyViewHolder(view);
view.setTag(myViewHolder);
}
MyViewHolder myViewHolder = (MyViewHolder)view.getTag();
myViewHolder.img.setImageBitmap(bitmaps.get(i));
return view;
}
public class MyViewHolder {
public ImageView img;
public MyViewHolder(View view) {
img = view.findViewById(R.id.image1);
}
}
}

Related

onClick for images in ViewPager

I've a image slider made with the help of ViewPager. I want to show different toast messages when clicked in different images loaded by ViewPager, how can i do that?
this my activity where image slider is shown:
public class MainActivity extends AppCompatActivity{
public static final String MAIN = "OTHER";
private static ViewPager mPager;
private static int currentPage = 0;
private static final Integer[] XMEN=
{R.drawable.benz2, R.drawable.benz2,
R.drawable.benz2};
private ArrayList<Integer> XMENArray = new ArrayList<Integer>();
#Override
protected void onCreate(...);
init();
}
private void init() {
for(int i=0;i<XMEN.length;i++)
XMENArray.add(XMEN[i]);
mPager = (ViewPager) findViewById(R.id.pager);
mPager.setAdapter(new com.example.nepali_test.MyAdapter(MainActivity.this,XMENArray));
CircleIndicator indicator = (CircleIndicator) findViewById(R.id.indicator);
indicator.setViewPager(mPager);
final Handler handler = new Handler();
final Runnable Update = new Runnable() {
public void run() {
if (currentPage == XMEN.length) {
currentPage = 0;
}
mPager.setCurrentItem(currentPage++, true);
}
};
Timer swipeTimer = new Timer();
swipeTimer.schedule(new TimerTask() {
#Override
public void run() {
handler.post(Update);
}
}, 3000, 3000);
}
and this is the adapter of the viewpager:
public class MyAdapter extends PagerAdapter {
private ArrayList<Integer> images;
private LayoutInflater inflater;
private Context context;
public MyAdapter(Context context, ArrayList<Integer> images) {
this.context = context;
this.images=images;
inflater = LayoutInflater.from(context);
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
#Override
public int getCount() {
return images.size();
}
#Override
public Object instantiateItem(ViewGroup view, int position) {
View myImageLayout = inflater.inflate(R.layout.slide, view, false);
ImageView myImage = (ImageView) myImageLayout
.findViewById(R.id.image);
myImage.setImageResource(images.get(position));
view.addView(myImageLayout, 0);
return myImageLayout;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view.equals(object);
}
}
I tried to make by adding
if (currentPage==1){
Toast.makeText(this, "page 1", Toast.LENGTH_SHORT).show();
}
in init() but it didn't work.
From what i could understand you need to display the toast when clicking on the image in each page of a ViewPager in which case an easy way is to add an onClickListener to your ImageView inside your adapter's instantiateItem method. So you should change/replace your method with this:
#NonNull
#Override
public Object instantiateItem(#NonNull final ViewGroup view, final int position) {
View myImageLayout = inflater.inflate(R.layout.slide, view, false);
ImageView myImage = (ImageView) myImageLayout
.findViewById(R.id.image);
myImage.setImageResource(images.get(position));
myImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context.getApplicationContext(), "page "+position, Toast.LENGTH_SHORT).show();
}
});
view.addView(myImageLayout, 0);
return myImageLayout;
}
Try this:
#Override
public Object instantiateItem(View collection, final int pos) { //have to make final so we can see it inside of onClick()
LayoutInflater inflater = (LayoutInflater) collection.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View page = inflater.inflate(R.layout.YOUR_PAGE, null);
page.setOnClickListener(new OnClickListener(){
public void onClick(View v){
//this will log the page number that was click
Log.i("TAG", "This page was clicked: " + pos);
}
});
((ViewPager) collection).addView(page, 0);
return page;
}
Hope this will work!
Make Image click interface in adapter class
public class MyAdapter extends PagerAdapter {
private ArrayList<Integer> images;
private LayoutInflater inflater;
private Context context;
MyClassImage myClassImage;
public interface MyClassImage{
void imageClick(String id);
}
public ViewPagerAdapter(Context context, ArrayList<Integer> images,MyClassImage myClassImage) {
this.context = context;
this.images=images;
this.myClassImage=myClassImage;
inflater = LayoutInflater.from(context);
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
#Override
public int getCount() {
return images.size();
}
#Override
public Object instantiateItem(ViewGroup view, int position) {
View myImageLayout = inflater.inflate(R.layout.z_slide_pager_item, view, false);
ImageView myImage = (ImageView) myImageLayout.findViewById(R.id.image);
myImage.setImageResource(images.get(position));
view.addView(myImageLayout, 0);
final int id=images.get(position);
final String imgId=String.valueOf(id);
myImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
myClassImage.imageClick(imgId);
}
});
return myImageLayout;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view.equals(object);
}
}
and implement it on your MainActivity class
public class MainActivity extends AppCompatActivity implements MyAdapter.MyClassImage {
public static final String MAIN = "OTHER";
private static ViewPager mPager;
private static int currentPage = 0;
private static final Integer[] XMEN= {R.drawable.benz2, R.drawable.benz2, R.drawable.benz2};
private ArrayList<Integer> XMENArray = new ArrayList<Integer>();
#Override
protected void onCreate(...);
init();
}
private void init() {
for(int i=0;i<XMEN.length;i++)
XMENArray.add(XMEN[i]);
mPager = (ViewPager) findViewById(R.id.pager);
mPager.setAdapter(new com.example.nepali_test.MyAdapter(MainActivity.this,XMENArray,this));
CircleIndicator indicator = (CircleIndicator) findViewById(R.id.indicator);
indicator.setViewPager(mPager);
final Handler handler = new Handler();
final Runnable Update = new Runnable() {
public void run() {
if (currentPage == XMEN.length) {
currentPage = 0;
}
mPager.setCurrentItem(currentPage++, true);
}
};
Timer swipeTimer = new Timer();
swipeTimer.schedule(new TimerTask() {
#Override
public void run() {
handler.post(Update);
}
}, 3000, 3000);
}
#Override
public void imageClick(String id) {
Toast.makeText(this, "page "+id, Toast.LENGTH_SHORT).show();
}
Hope it will be helpful to you.
Thanks.

How can I get a variable from RecyclerView Adapter passed to MainActivity?

I was just playing around with some code, learning new things, when I ran into this problem... I'm trying to pass a variable from my RecylcerViewAdapter to a method in MainActivity, but I just can't seem to accomplish it.
I tried a lot of different thing with interfaces and casting, but nothing did the trick. Since I'm fairly new to all of this, maybe I'm making a trivial mistake somewhere?
My Interface:
public interface AdapterCallback {
void onMethodCallback(int id);
}
This is my adapter class:
public class PostAdapter extends RecyclerView.Adapter<PostAdapter.ViewHolder> {
private List<Post> postList;
private Context context;
private AdapterCallback listener;
public PostAdapter() {
}
public PostAdapter(List<Post> postList, Context context) {
this.postList = postList;
this.context = context;
}
public void setListener(AdapterCallback listener) {
this.listener = listener;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.recycler_layout, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder viewHolder, final int position) {
viewHolder.tvTitle.setText(postList.get(position).getTitle());
viewHolder.tvBody.setText(new StringBuilder(postList.get(position).getBody().substring(0, 20)).append("..."));
viewHolder.tvId.setText(String.valueOf(postList.get(position).getUserId()));
viewHolder.parentLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int id = postList.get(position).getId();
if (listener != null) {
listener.onMethodCallback(id);
}
}
});
}
#Override
public int getItemCount() {
return postList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView tvTitle;
TextView tvBody;
TextView tvId;
LinearLayout parentLayout;
public ViewHolder(View itemView) {
super(itemView);
tvTitle = itemView.findViewById(R.id.tvTitle);
tvBody = itemView.findViewById(R.id.tvBody);
tvId = itemView.findViewById(R.id.tvId);
parentLayout = itemView.findViewById(R.id.parentLayout);
}
}
}
And my MainActivity:
public class MainActivity extends AppCompatActivity {
public static final String TAG = "MainActivityLog";
private CompositeDisposable disposable = new CompositeDisposable();
#BindView(R.id.rvPosts)
RecyclerView rvPosts;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
rvPosts.setHasFixedSize(true);
rvPosts.setLayoutManager(new LinearLayoutManager(this));
populateList();
logItems();
}
private void populateList() {
MainViewModel viewModel = ViewModelProviders.of(MainActivity.this).get(MainViewModel.class);
viewModel.makeQuery().observe(MainActivity.this, new Observer<List<Post>>() {
#Override
public void onChanged(#Nullable List<Post> posts) {
PostAdapter adapter = new PostAdapter(posts, getApplicationContext());
rvPosts.setAdapter(adapter);
}
});
}
public void logItems() {
PostAdapter adapter = new PostAdapter();
adapter.setListener(new AdapterCallback() {
#Override
public void onMethodCallback(int id) {
MainViewModel viewModel = ViewModelProviders.of(MainActivity.this).get(MainViewModel.class);
viewModel.makeSingleQuery(id).observe(MainActivity.this, new Observer<Post>() {
#Override
public void onChanged(#Nullable final Post post) {
Log.d(TAG, "onChanged: data response");
Log.d(TAG, "onChanged: " + post);
}
});
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
disposable.clear();
}
}
The populateList() method works just fine, but the logItems() method is the problem.
So when i click on a view in RecyclerView I expect the log to output the title, description and ID of the post that was clicked. nut nothing happens...
So, any help would be appreciated.
Make adapter global variable i.e. a field. Use the same object to set every properties.
private PostAdapter adapter;
Replace your logItems method with this:
public void logItems() {
adapter.setListener(new AdapterCallback() {
#Override
public void onMethodCallback(int id) {
MainViewModel viewModel = ViewModelProviders.of(MainActivity.this).get(MainViewModel.class);
viewModel.makeSingleQuery(id).observe(MainActivity.this, new Observer<Post>() {
#Override
public void onChanged(#Nullable final Post post) {
Log.d(TAG, "onChanged: data response");
Log.d(TAG, "onChanged: " + post);
}
});
}
});
}
And populateList with this:
private void populateList() {
MainViewModel viewModel = ViewModelProviders.of(MainActivity.this).get(MainViewModel.class);
viewModel.makeQuery().observe(MainActivity.this, new Observer<List<Post>>() {
#Override
public void onChanged(#Nullable List<Post> posts) {
adapter = new PostAdapter(posts, getApplicationContext());
rvPosts.setAdapter(adapter);
logItems();
}
});
}
And don't call logItems() from onCreate
This is how I implement with my ListAdapters:
public class FeedbackListAdapter extends RecyclerView.Adapter<FeedbackListAdapter.ViewHolder> {
private final ArrayList<Feedback> feedbacks;
private View.OnClickListener onItemClickListener;
private View.OnLongClickListener onItemLongClickListener;
private final Context context;
public FeedbackListAdapter(ArrayList<Feedback> feedbacks, Context context) {
this.feedbacks = feedbacks;
this.context = context;
}
public void setItemClickListener(View.OnClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
public void setOnItemLongClickListener(View.OnLongClickListener onItemLongClickListener){
this.onItemLongClickListener = onItemLongClickListener;
}
public class ViewHolder extends RecyclerView.ViewHolder{
final TextView feedback, created, updated;
final LinearLayout mainLayout;
ViewHolder(View iv) {
super(iv);
/*
* Associate layout elements to Java declarations
* */
mainLayout = iv.findViewById(R.id.main_layout);
feedback = iv.findViewById(R.id.feedback);
created = iv.findViewById(R.id.created_string);
updated = iv.findViewById(R.id.updated_string);
}
}
#Override
public int getItemCount() {
return feedbacks.size();
}
#Override
#NonNull
public FeedbackListAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fragment_feedback_table_row, parent, false);
return new FeedbackListAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(final #NonNull FeedbackListAdapter.ViewHolder holder, final int position) {
/*
* Bind data to layout
* */
try{
Feedback feedback = feedbacks.get(position);
holder.feedback.setText(feedback.getContent());
holder.created.setText(feedback.getCreated());
holder.updated.setText(feedback.getUpdated());
holder.mainLayout.setOnClickListener(this.onItemClickListener);
holder.mainLayout.setOnLongClickListener(this.onItemLongClickListener);
holder.mainLayout.setTag(feedback.getDbID());
TypedValue outValue = new TypedValue();
context.getTheme().resolveAttribute(android.R.attr.selectableItemBackground, outValue, true);
holder.mainLayout.setBackgroundResource(outValue.resourceId);
}catch(IndexOutOfBoundsException e){
e.printStackTrace();
}
}
}
In onPopulateList you create an adaptor:
PostAdapter adapter = new PostAdapter(posts, getApplicationContext());
rvPosts.setAdapter(adapter);
However in public void logItems() { you used a different adapter
PostAdapter adapter = new PostAdapter();
adapter.setListener(new AdapterCallback() {
#Override
public void onMethodCallback(int id) {
...
}
});
Therefore the list is being populated with 1 adapter, but you are setting the listener on an unused second adapter.
The fix is to use the same adapter for both. If you make the adapater a field, and don't create a new one inside of logItems, but just set your listener it should work.
i.e.
// as a field in your class
private PostAdapter adapter;
then
// in `populateList()`
adapter = new PostAdapter(posts, getApplicationContext());
rvPosts.setAdapter(adapter);
and
// in `logItems()`
adapter.setListener(new AdapterCallback() {
#Override
public void onMethodCallback(int id) {
...
}
});
In Adapter
public class CustomerListAdapter extends RecyclerView.Adapter<CustomerListAdapter.OrderItemViewHolder> {
private Context mCtx;
ProgressDialog progressDialog;
//we are storing all the products in a list
private List<CustomerModel> customeritemList;
public CustomerListAdapter(Context mCtx, List<CustomerModel> orderitemList) {
this.mCtx = mCtx;
this.customeritemList = orderitemList;
progressDialog = new ProgressDialog(mCtx);
}
#NonNull
#Override
public OrderItemViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mCtx);
View view = inflater.inflate(R.layout.activity_customer_list, null);
return new OrderItemViewHolder(view, mCtx, customeritemList);
}
#Override
public void onBindViewHolder(#NonNull OrderItemViewHolder holder, int position) {
CustomerModel customer = customeritemList.get(position);
try {
//holder.textViewPINo.setText("PINo \n"+Integer.toString( order.getPINo()));
holder.c_name.setText(customer.getCustomerName());
holder.c_address.setText(customer.getAddress());
holder.c_contact.setText(customer.getMobile());
holder.i_name.setText(customer.getInteriorName());
holder.i_contact.setText(customer.getInteriorMobile());
holder.i_address.setText(customer.getAddress());
} catch (Exception E) {
E.printStackTrace();
}
}
#Override
public int getItemCount() {
return customeritemList.size();
}
class OrderItemViewHolder extends RecyclerView.ViewHolder implements View.OnLongClickListener, View.OnClickListener {
AlertDialog.Builder alert;
private Context mCtx;
TextView c_name, c_contact, c_address, i_name, i_contact, i_address;
TextView OrderItemID, MaterialType, Price2, Qty, AQty;
//we are storing all the products in a list
private List<CustomerModel> orderitemList;
public OrderItemViewHolder(View itemView, Context mCtx, List<CustomerModel> orderitemList) {
super(itemView);
this.mCtx = mCtx;
this.orderitemList = orderitemList;
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
// CatelogOrderDetailModel catelogOrderDetailModel = new CatelogOrderDetailModel();
c_name = itemView.findViewById(R.id.customerName);
c_contact = itemView.findViewById(R.id.contact);
c_address = itemView.findViewById(R.id.address);
i_name = itemView.findViewById(R.id.interiorName);
i_address = itemView.findViewById(R.id.interiorAddress);
i_contact = itemView.findViewById(R.id.interiorContact);
}
#Override
public void onClick(View v) {
int position = getAdapterPosition();
CustomerModel orderitem = this.orderitemList.get(position);
}
#Override
public boolean onLongClick(View v) {
int position = getAdapterPosition();
CustomerModel orderitem = this.orderitemList.get(position);
if (v.getId() == itemView.getId()) {
// showUpdateDeleteDialog(order);
try {
} catch (Exception E) {
E.printStackTrace();
}
Toast.makeText(mCtx, "lc: ", Toast.LENGTH_SHORT).show();
}
return true;
}
}
}

Android volley singleton and custom gridview adapter

I am using a custom gridview adapter to show images with volley singleton. But when I run it it returns the onErrorResponse. It looks like the adapter is not even set properly, is it something with where i set the adapter? I have tried setting it in onCreate but same error.
The adapter class looked fine so I think the problem is in MainActivity.
MainActivity.java:
public class MainActivity extends AppCompatActivity {
private final int THUMBNAIL_SIZE = 250;
private final String KEY = "IMAGE";
ArrayList<Bitmap> bitmaps = new ArrayList<Bitmap>();
private static final String URLS[] = {
"http://10.0.2.2/Android%20A4_1/germany.png",
"http://10.0.2.2/Android%20A4_1/indonesia.png",
"http://10.0.2.2/Android%20A4_1/japan.png",
"http://10.0.2.2/Android%20A4_1/sarawak.png",
"http://10.0.2.2/Android%20A4_1/singapore.png",
"http://10.0.2.2/Android%20A4_1/switzerland.png",
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
for(int i = 0; i<URLS.length; i++) {
LoadingImages(URLS[i]);
}
}
private void LoadingImages(String url) {
ImageLoader imageLoader = MySingleton.getInstance(getApplicationContext()).getImageLoader();
imageLoader.get(url, new ImageLoader.ImageListener() {
#Override
public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) {
Bitmap image = response.getBitmap();
Bitmap thumbnail = ThumbnailUtils.extractThumbnail(image, THUMBNAIL_SIZE, THUMBNAIL_SIZE);
bitmaps.add(thumbnail);
GridView gridView = (GridView)findViewById(R.id.grid_layout);
final ImageAdapter imageAdapter = new ImageAdapter(MainActivity.this, bitmaps);
gridView.setAdapter(imageAdapter);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Intent intent = new Intent(getApplicationContext(), Main2Activity.class);
intent.putExtra(KEY, URLS[i]);
startActivity(intent);
}
});
}
#Override
public void onErrorResponse(VolleyError error) {
Log.e("error", error.getMessage());
}
});
}
}
The Adapter class:
public class ImageAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<Bitmap> bitmaps;
public ImageAdapter(Context context, ArrayList<Bitmap> bitmaps) {
this.mContext = context;
this.bitmaps = bitmaps;
}
#Override
public int getCount() {
return 0;
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
if (view == null) {
final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
view = layoutInflater.inflate(R.layout.griditems, null);
MyViewHolder myViewHolder = new MyViewHolder(view);
view.setTag(myViewHolder);
}
MyViewHolder myViewHolder = (MyViewHolder)view.getTag();
myViewHolder.img.setImageBitmap(bitmaps.get(i));
return view;
}
public class MyViewHolder {
public ImageView img;
public MyViewHolder(View view) {
img = view.findViewById(R.id.image1);
}
}
}
My Singleton:
public class MySingleton {
private static MySingleton instance;
private RequestQueue requestQueue;
private ImageLoader imageLoader;
private static Context context;
private MySingleton(Context context){
this.context = context;
requestQueue = Volley.newRequestQueue(context);
imageLoader = new ImageLoader(requestQueue, new ImageLoader.ImageCache() {
private final LruCache<String, Bitmap> cache = new LruCache<>(6);
#Override
public Bitmap getBitmap(String url) {
Bitmap bmp = cache.get(url);
if (bmp == null) {
System.out.println("Not in cache");
} else {
System.out.println("In cache");
}
return bmp;
}
#Override
public void putBitmap(String url, Bitmap bitmap) {
System.out.println("Put in cache");
cache.put(url, bitmap);
}
});
}
public static synchronized MySingleton getInstance(Context context) {
if (instance == null) {
instance = new MySingleton(context);
}
return instance;
}
public ImageLoader getImageLoader() {
return imageLoader;
}
}
Main2Activity:
public class Main2Activity extends AppCompatActivity {
private ImageView imageView;
private final String KEY = "IMAGE";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
imageView = (ImageView)findViewById(R.id.imageView);
Bundle bundle = getIntent().getExtras();
String url = bundle.getString(KEY);
LoadingImages(url);
}
private void LoadingImages(String url) {
final ImageLoader imageLoader = MySingleton.getInstance(getApplicationContext()).getImageLoader();
imageLoader.get(url, new ImageLoader.ImageListener() {
#Override
public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) {
Bitmap bitmap = response.getBitmap();
imageView.setImageBitmap(bitmap);
}
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Error", error.getMessage());
}
});
}
}
change This methods
#Override
public int getCount() {
return 0;
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
To
#Override
public int getCount() {
return bitmaps.size;
}
#Override
public Object getItem(int i) {
return bitmaps.get(i);
}
#Override
public long getItemId(int i) {
return i;
}

How to Pass Image or path from Recyclerview to next Activity onClick so that i can display Image Full View?

I really don't know how to do this. I have tried some tutorial but not worked for me ... i've already done the this with many Methods but unable to do this.
Here is my RecyclerView Holder
public class RecyclerViewHolders extends RecyclerView.ViewHolder implements View.OnClickListener{
public TextView countryName;
public ImageView countryPhoto;
String s;
Bitmap image;
public RecyclerViewHolders(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
countryPhoto = (ImageView)itemView.findViewById(R.id.country_photo);
}
#Override public void onClick(View view) {
Intent imageIntent = new Intent(view.getContext(),GalleryFullImage.class);
imageIntent.putExtra("id",getAdapterPosition());
view.getContext().startActivity(imageIntent);
Toast.makeText(view.getContext(), "Clicked Country Position = " + getAdapterPosition(), Toast.LENGTH_SHORT).show();
}}
Here is my Recyclerview Adapter
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewHolders> {
private ArrayList<String> arrayList;
private Context context;
public RecyclerViewAdapter(Context context, ArrayList<String> itemList) {
this.arrayList = itemList;
this.context = context;
}
#Override
public long getItemId(int position) {
return position;
}
#Override public RecyclerViewHolders onCreateViewHolder(ViewGroup parent, int viewType) {
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.gallery_item, null);
RecyclerViewHolders rcv = new RecyclerViewHolders(layoutView);
return rcv;
}
#Override public void onBindViewHolder(RecyclerViewHolders holder, int position) {
Bitmap bitmap = BitmapFactory.decodeFile(arrayList.get(position));
holder.countryPhoto.setImageBitmap(bitmap);
}
#Override public int getItemCount() {
return this.arrayList.size();
}}
Here is my GalleryActivity
public class GalleryActivity extends AppCompatActivity {
ArrayList<String> stringList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activty_gallery);
setTitle("Gallery");
stringList = new ArrayList<>();
// Be sure that this file is exist !!
String targetPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Country";
File targetDirector = new File(targetPath);
File[] files = targetDirector.listFiles();
try
{
Arrays.sort( files, new Comparator()
{
public int compare(Object o1, Object o2) {
if (((File)o1).lastModified() > ((File)o2).lastModified()) {
return -1;
} else if (((File)o1).lastModified() < ((File)o2).lastModified()) {
return +1;
} else {
return 0;
}
}
});
for (File file : files) {
stringList.add(file.getAbsolutePath());
}
}catch (Exception e)
{
Log.e("Sort Error", e.getMessage());
}
RecyclerView rView = (RecyclerView)findViewById(R.id.my_recycler_view);
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getApplicationContext(),2);
rView.setHasFixedSize(true);
rView.setLayoutManager(layoutManager);
RecyclerViewAdapter rcAdapter = new RecyclerViewAdapter(getApplicationContext(), stringList);
rView.setAdapter(rcAdapter);
}
}
You just have to apply onClickListener in you viewholder, take the clicked adapter position in integer and pass it in next your fullscreen activity
Here is the full code, hope it helps
MainActivity
public class MainActivity extends AppCompatActivity {
private final Integer image_ids[] = {
R.drawable.image1,
R.drawable.image2,
R.drawable.image3,
R.drawable.image4,
R.drawable.image5,
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recyclerview);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getApplicationContext(),gridColumnlayout);
recyclerView.setLayoutManager(layoutManager);
ArrayList<CreateList> createLists = prepareData();
MyAdapter adapter = new MyAdapter(getApplicationContext(), createLists);
recyclerView.setAdapter(adapter);
}
private ArrayList<CreateList> prepareData(){
ArrayList<CreateList> theimage = new ArrayList<>();
for(int i = 0; i< 5; i++){
CreateList createList = new CreateList();
createList.setImage_ID(image_ids[i]);
theimage.add(createList);
}
return theimage;
}
}
CreateList Class
public class CreateList {
private Integer image_id;
public Integer getImage_ID() {
return image_id;
}
public void setImage_ID(Integer android_image_url) {
this.image_id = android_image_url;
}
}
MyAdapter
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private ArrayList<CreateList> galleryList;
private Context context;
public final static String EXTRA_MESSAGE = "FullScreen Image";
public MyAdapter(Context context, ArrayList<CreateList> galleryList) {
this.galleryList = galleryList;
this.context = context;
}
#Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int i) {
return new ViewHolder(LayoutInflater.from(context).inflate(R.layout.list_item, parent, false));
}
#Override
public void onBindViewHolder(final MyAdapter.ViewHolder viewHolder, int i) {
CreateList currentList = galleryList.get(i);
Glide.with(context).load(currentList.getImage_ID()).centerCrop().crossFade().into(viewHolder.img);
viewHolder.img.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int pos = viewHolder.getAdapterPosition();
String stringID = Integer.valueOf(pos).toString();
Intent intent = new Intent(MyAdapter.this.context, FullScreen.class);
intent.putExtra(EXTRA_MESSAGE, stringID);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return galleryList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private ImageView img;
public ViewHolder(View view) {
super(view);
img = (ImageView) view.findViewById(R.id.image);
}
}
}
FullScreen Activity
public class FullScreen extends AppCompatActivity {
private final Integer image_ids[] = {
R.drawable.image1,
R.drawable.image2,
R.drawable.image3,
R.drawable.image4,
R.drawable.image5,
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_full_screen);
Intent intent = getIntent();
String message = intent.getStringExtra(MyAdapter.EXTRA_MESSAGE);
int position = Integer.parseInt(message);
ImageView imageView = (ImageView) viewItem.findViewById(R.id.imageView);
imageView.setImageResource(image_ids[position]);
}
}
list_item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="match_parent"
android:layout_height="170dp"
android:scaleType="fitXY"
android:id="#+id/image"/>
</RelativeLayout>
Since you are loading the bitmap from file in onBindViewHolder, you can just pass the path instead in onClick and decode it again in your next activity. This may require a bit of work in your case since your ViewHolder is defined separately from your RecyclerView so it does not have access to your dataset. For starters, move your ViewHolder so it can be a static nested class of your RecyclerView. Something like this:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecyclerViewHolders>
private ArrayList<String> arrayList;
....
public static class RecyclerViewHolders extends RecyclerView.ViewHolder implements View.OnClickListener{
....
#Override
public void onClick(View view) {
Intent intent = new Intent(...);
intent.putExtra("path",arrayList.get(getAdapterPosition());
/* send intent*/
}
}

How to implement coverflow layout from existing gridview images

i am using eclipse.
Basically what i am trying to implement is that , that i have a gridView which is fetching images from mysql database dynamically using JSON.
Now , instead of gridview i want to show them as coverflow view.
I have searched through the internet , but was not able to find any library or example for dynamic images , i only found for static images stored in the app itself and not on external database.
My code are as follows:-
MainActivity.java:-
public class MainActivity extends Activity implements OnClickListener {
// Log tag
private static final String TAG = MainActivity.class.getSimpleName();
// Movies json url
private static final String url = "http://eventassociate.com/wedding/photomania";
private ProgressDialog pDialog;
private List<Movie> movieList = new ArrayList<Movie>();
private PullToRefreshGridView mPullRefreshGridView;
private GridView gridView;
private CustomListAdapter adapter;
ImageButton blackcapture;
private static int RESULT_LOAD_IMAGE = 1;
String picturePath;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.gallary_activity_main);
overridePendingTransition(R.anim.push_down_in, R.anim.push_down_out);
mPullRefreshGridView = (PullToRefreshGridView) findViewById(R.id.list);
gridView = mPullRefreshGridView.getRefreshableView();
mPullRefreshGridView.setOnRefreshListener(new OnRefreshListener2<GridView>() {
#Override
public void onPullDownToRefresh(PullToRefreshBase<GridView> refreshView) {
adapter.notifyDataSetChanged();
gridView.setAdapter(adapter);
gridView.invalidateViews();
mPullRefreshGridView.onRefreshComplete();
}
adapter = new CustomListAdapter(this, movieList);
gridView.setAdapter(adapter);
gridView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
Movie m5 = movieList.get(position);
Intent i = new Intent(getApplicationContext(),
FullImageActivity.class);
i.putExtra("movieobject", m5);
startActivity(i);
}
});
Adapter Class:-
public class CustomListAdapter extends BaseAdapter {
private Activity activity;
private LayoutInflater inflater;
List<Movie> movieItems;
ImageLoader imageLoader = AppController.getInstance().getImageLoader();
public CustomListAdapter(Activity activity, List<Movie> movieItems) {
this.activity = activity;
this.movieItems = movieItems;
}
#Override
public int getCount() {
return movieItems.size();
}
#Override
public Object getItem(int location) {
return movieItems.get(location);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (inflater == null)
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
convertView = inflater.inflate(R.layout.gallary_list_row, null);
if (imageLoader == null)
imageLoader = AppController.getInstance().getImageLoader();
NetworkImageView thumbNail = (NetworkImageView) convertView
.findViewById(R.id.thumbnail);
// ...............................................
TextView title = (TextView) convertView.findViewById(R.id.title);
// getting movie data for the row
Movie m = movieItems.get(position);
// thumbnail image
thumbNail.setImageUrl(m.getThumbnailUrl(), imageLoader);
// title
title.setText(m.getTitle());
return convertView;
}
Movie.java:-
public class Movie implements Parcelable{
private String title,thumbnailUrl;
public Movie() {
// TODO Auto-generated constructor stub
}
public Movie(String name, String thumbnailUrl
) {
this.title = name;
this.thumbnailUrl = thumbnailUrl;
}
public String getTitle() {
return title;
}
public void setTitle(String name) {
this.title = name;
}
public String getThumbnailUrl() {
return thumbnailUrl;
}
public void setThumbnailUrl(String thumbnailUrl) {
this.thumbnailUrl = "http://eventassociate.com/wedding/"+thumbnailUrl;
}
// Parcelling part
public Movie(Parcel in){
String[] data = new String[2];
in.readStringArray(data);
this.title = data[0];
this.thumbnailUrl = data[1];
}
#Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeStringArray(new String[] {this.title,
this.thumbnailUrl,
});
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public Movie createFromParcel(Parcel in) {
return new Movie(in);
}
public Movie[] newArray(int size) {
return new Movie[size];
}
};
}
I successfully implemented this as GridView , but i am facing trouble in implementing this as coverflow design or something like that.
I searched on the net and i find this code , but only for static images:-
public class SimpleExample extends Activity {
// =============================================================================
// Child views
// =============================================================================
private FancyCoverFlow fancyCoverFlow;
// =============================================================================
// Supertype overrides
// =============================================================================
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
this.fancyCoverFlow = (FancyCoverFlow) this.findViewById(R.id.fancyCoverFlow);
this.fancyCoverFlow.setAdapter(new FancyCoverFlowSampleAdapter());
this.fancyCoverFlow.setUnselectedAlpha(1.0f);
this.fancyCoverFlow.setUnselectedSaturation(0.0f);
this.fancyCoverFlow.setUnselectedScale(0.5f);
this.fancyCoverFlow.setSpacing(50);
this.fancyCoverFlow.setMaxRotation(0);
this.fancyCoverFlow.setScaleDownGravity(0.2f);
this.fancyCoverFlow.setActionDistance(FancyCoverFlow.ACTION_DISTANCE_AUTO);
}
// =============================================================================
// Private classes
// =============================================================================
}
Adapter.java:-
public class FancyCoverFlowSampleAdapter extends FancyCoverFlowAdapter {
// =============================================================================
// Private members
// =============================================================================
private int[] images = {R.drawable.image1, R.drawable.image2, R.drawable.image3, R.drawable.image4, R.drawable.image5, R.drawable.image6,};
// =============================================================================
// Supertype overrides
// =============================================================================
#Override
public int getCount() {
return images.length;
}
#Override
public Integer getItem(int i) {
return images[i];
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getCoverFlowItem(int i, View reuseableView, ViewGroup viewGroup) {
ImageView imageView = null;
if (reuseableView != null) {
imageView = (ImageView) reuseableView;
} else {
imageView = new ImageView(viewGroup.getContext());
imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
imageView.setLayoutParams(new FancyCoverFlow.LayoutParams(300, 400));
}
imageView.setImageResource(this.getItem(i));
return imageView;
}
}
Can someone help me , in solving my problem.
Thanks.
My final code with coverflow:-
MainActivity:-
public class MainActivity extends Activity implements OnClickListener {
// Log tag
private static final String TAG = album.MainActivity.class.getSimpleName();
// Movies json url
private static final String url = "http://eventassociate.com/wedding/androidadminimages";
private ProgressDialog pDialog;
private List<Moviealbum> movieList = new ArrayList<Moviealbum>();
private FancyCoverFlow fancyCoverFlow;
private CustomListAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.album_activity_main);
overridePendingTransition(R.anim.push_down_in, R.anim.push_down_out);
this.fancyCoverFlow = (FancyCoverFlow) this.findViewById(R.id.list);
adapter = new CustomListAdapter(this, movieList);
this.fancyCoverFlow.setAdapter(new CustomListAdapter(this, movieList));
this.fancyCoverFlow.setUnselectedAlpha(1.0f);
this.fancyCoverFlow.setUnselectedSaturation(0.0f);
this.fancyCoverFlow.setUnselectedScale(0.5f);
this.fancyCoverFlow.setSpacing(50);
this.fancyCoverFlow.setMaxRotation(0);
this.fancyCoverFlow.setScaleDownGravity(0.2f);
this.fancyCoverFlow.setActionDistance(FancyCoverFlow.ACTION_DISTANCE_AUTO);
fancyCoverFlow.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
Moviealbum m5 = movieList.get(position);
Intent i = new Intent(getApplicationContext(),album.
FullImageActivity.class);
i.putExtra("movieobject", m5);
startActivity(i);
}
});
pDialog = new ProgressDialog(this);
// Showing progress dialog before making http request
pDialog.setMessage("Loading...");
pDialog.show();
// changing action bar color
getActionBar().setBackgroundDrawable(
new ColorDrawable(Color.parseColor("#1b1b1b")));
// Creating volley request obj
JsonArrayRequest movieReq = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
hidePDialog();
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
Moviealbum movie = new Moviealbum();
movie.setTitle(obj.getString("no"));
movie.setThumbnailUrl(obj.getString("alinks"));
// adding movie to movies array
movieList.add(movie);
} catch (JSONException e) {
e.printStackTrace();
}
}
// notifying list adapter about data changes
// so that it renders the list view with updated data
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
hidePDialog();
}
});
// Adding request to request queue...................................
AppController.getInstance().addToRequestQueue(movieReq);
}
#Override
public void onDestroy() {
super.onDestroy();
hidePDialog();
}
private void hidePDialog() {
if (pDialog != null) {
pDialog.dismiss();
pDialog = null;
}
}
AdapterClass :-
public class CustomListAdapter extends FancyCoverFlowAdapter {
private Activity activity;
private LayoutInflater inflater;
List<Moviealbum> movieItems;
ImageLoader imageLoader = AppController.getInstance().getImageLoader();
public CustomListAdapter(Activity activity, List<Moviealbum> movieItems) {
this.activity = activity;
this.movieItems = movieItems;
}
#Override
public int getCount() {
return movieItems.size();
}
#Override
public Object getItem(int location) {
return movieItems.get(location);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getCoverFlowItem(int position, View reuseableView, ViewGroup viewGroup) {
if (inflater == null)
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (reuseableView == null)
reuseableView = inflater.inflate(R.layout.gallary_list_row, null);
if (imageLoader == null)
imageLoader = AppController.getInstance().getImageLoader();
NetworkImageView thumbNail = (NetworkImageView) reuseableView
.findViewById(R.id.thumbnail);
// ...............................................
TextView title = (TextView) reuseableView.findViewById(R.id.title);
// getting movie data for the row
Moviealbum m = movieItems.get(position);
// thumbnail image
thumbNail.setImageUrl(m.getThumbnailUrl(), imageLoader);
// title
title.setText(m.getTitle());
return reuseableView;
}
The app runs fine , but after loading blank screen is shown with no images.
Logcat:-
Your issue isn't with the CoverFlow code, but rather where you're doing your network operation. On app load, begin your network request for your JSON payload, show a spinner to show the app is loading, and populate your Adapter once your images are loaded. I'm assuming you have network code already given your GridView implementation? Let me know if I've missed something. I hope that helps!
EDIT:
Once you've added images to your Adapter make sure you call notifyDataSetChanged() to tell your adapter to reload its views.
EDIT 2:
Look at this line here:
this.fancyCoverFlow.setAdapter(new CustomListAdapter(this, movieList));
You're passing a new CustomListAdapter rather than passing in your adapter variable. Try fixing that and let me know if it works.

Categories

Resources