I am trying to load images into RecyclerView Adapater I am getting errors with
if(photo!=null) - Unexpected Token.
return newPhotoFilterViewHolder(view); - Invalid Declaration Return Type Required.
public class PhotoFiltersAdapter extends RecyclerView.Adapter - Declare abstract or create abstract method.
Here is my code for the implementation to load Images into RecyclerViewAdapter
public class PhotoFiltersAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private int itemsCount = 12;
ImageView image;
// Fields for the map radius in feet
private float radius = InstaMaterialApplication.getSearchDistance();
/**
* Helper class to get the user location.
*/
private GeoLocationHelper geoLocationHelper = new GeoLocationHelper();
// Adapter for the Parse query
private ParseQueryAdapter<FilterImages> postsQueryAdapter;
public PhotoFiltersAdapter(Context context) {
this.context = context;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(final FilterImages post, ViewGroup parent, int viewType) {
final View view = LayoutInflater.from(context).inflate(R.layout.item_photo_filter, parent, false);
// Set up the query adapter
postsQueryAdapter = new ParseQueryAdapter<FilterImages>(this, factory) {
ParseFile photo = (ParseFile) post.get("image");
if(photo!=null)
{
photo.getDataInBackground(new GetDataCallback() {
#Override
public void done(byte[] data, ParseException e) {
// TODO Auto-generated method stub
if (data != null && e == null) {
Bitmap bitmap = BitmapFactory
.decodeByteArray(data, 0,
data.length);
image.setImageBitmap(bitmap);
} else {
//ParseException e
}
}
});
}
else
{
//picture_not_available
}
TextView contentView = (TextView) view.findViewById(R.id.content_view);
ImageView image=(ImageView)view.findViewById(R.id.picture_view);
TextView usernameView = (TextView) view.findViewById(R.id.username_view);
contentView.setText(post.getText());
return newPhotoFilterViewHolder(view);
};
}
private ParseGeoPoint geoPointFromLocation(Location loc) {
return new ParseGeoPoint(loc.getLatitude(), loc.getLongitude());
}
// Set up a customized query
ParseQueryAdapter.QueryFactory<FilterImages> factory =
new ParseQueryAdapter.QueryFactory<FilterImages>() {
public ParseQuery<FilterImages> create() {
Location myLoc = geoLocationHelper.getCurrentLocation();
ParseQuery query = FilterImages.getQuery();
query.include("PlaceName");
query.orderByDescending("AreaFilters");
query.whereWithinKilometers("AreaFilters", geoPointFromLocation(myLoc), radius);
query.setLimit(itemsCount);
return query;
}
};
#Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
}
#Override
public int getItemCount() {
return itemsCount;
}
public static class PhotoFilterViewHolder extends RecyclerView.ViewHolder {
public PhotoFilterViewHolder(View view) {
super(view);
ButterKnife.bind(this, view);
}
}
}
i have use glide to get image from Url, in ParseFile object have method .getUrl()
ParseFile photo = (ParseFile) post.get("image");
Glide.with(getActivity()).load(photo.getUrl()).centerCrop().diskCacheStrategy(DiskCacheStrategy.ALL).into(img_userProfilePicture_bg);
Related
I have read the google documentation and I have already fetched the photoreference key from my Nearby Search Requests. When we Run the URL of the google place photos API then we get the image. As I have only a URL, how to show that image URL on an image view.
My Modal Class:
public class PlacesResponse {
public class Root implements Serializable {
#SerializedName("results")
public ArrayList<CustomA> customA = new ArrayList<>();
#SerializedName("status")
public String status;
}
public class CustomA implements Serializable {
#SerializedName("geometry")
public Geometry geometry;
#SerializedName("vicinity")
public String vicinity;
#SerializedName("name")
public String name;
#SerializedName("photos")
public ArrayList<Photos> photos = new ArrayList<>();
#SerializedName("place_id")
public String place_id;
}
public class Photos implements Serializable{
#SerializedName("photo_reference")
public String photo_reference;
}
public class Geometry implements Serializable{
#SerializedName("location")
public LocationA locationA;
}
public class LocationA implements Serializable {
#SerializedName("lat")
public String lat;
#SerializedName("lng")
public String lng;
}
}
Code for Nearby Places Search request
private void fetchStores(String placeType) {
Call<PlacesResponse.Root> call = apiService.doPlaces(latLngString,radius,placeType, ApiClient.GOOGLE_PLACE_API_KEY);
call.enqueue(new Callback<Root>() {
#Override
public void onResponse(Call<PlacesResponse.Root> call, Response<PlacesResponse.Root> response) {
PlacesResponse.Root root = (Root) response.body();
if (response.isSuccessful()) {
if (root.status.equals("OK")) {
results = root.customA;
storeModels = new ArrayList<>();
distnaceModels = new ArrayList<>();
Log.i(TAG,"fetch stores");
for (int i = 0; i < results.size(); i++) {
PlacesResponse.CustomA info = (CustomA) results.get(i);
String place_id = results.get(i).place_id;
// this gives me the photo reference for the request
String photo_reference = results.get(i).photos.get(0).photo_reference;
fetchDistance(info);
// fetchPlace_details(place_id);
}
} else {
Toast.makeText(getApplicationContext(), "No matches found near you", Toast.LENGTH_SHORT).show();
}
} else if (response.code() != 200) {
Toast.makeText(getApplicationContext(), "Error " + response.code() + " found.", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call call, Throwable t) {
// Log error here since request failed
call.cancel();
}
});
}
Adapter Class
public class Rv_adapter extends RecyclerView.Adapter<MyViewHolder> {
private ArrayList<PlacesResponse.CustomA> stLstStores;
private ArrayList<Modal> storeModels;
private static final int TYPE_HEAD=0;
private static final int TYPE_LIST=1;
public Rv_adapter(ArrayList<PlacesResponse.CustomA> stLstStores, ArrayList<Modal> storeModels) {
this.stLstStores = stLstStores ;
this.storeModels = storeModels;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType==TYPE_LIST) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recyclerview_listitem, parent, false);
return new MyViewHolder(itemView,viewType);
}
else if(viewType==TYPE_HEAD)
{
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recyclerview_header, parent, false);
return new MyViewHolder(itemView,viewType);
}
return null;
}
#Override
public int getItemViewType(int position) {
if(position==0){
return TYPE_HEAD;}
else{
return TYPE_LIST;
}
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position)
{
Log.i("adapter_posn",holder.getAdapterPosition()+"");
Log.i("view type",holder.view_type+"");
if(holder.view_type == TYPE_LIST) {
holder.res_name.setText(stLstStores.get(holder.getAdapterPosition()-1).name);
// holder.res_address.setText(storeModels.get(holder.getAdapterPosition()-1).address);
// holder.res_phone.setText(storeModels.get(holder.getAdapterPosition()-1).phone_no);
// holder.res_rating.setText(String.valueOf(storeModels.get(holder.getAdapterPosition()-1).rating));
// holder.res_distance.setText(String.valueOf(storeModels.get(holder.getAdapterPosition()-1).distance));
}
else if (holder.view_type == TYPE_HEAD)
{
holder.current_location.setText(String.valueOf(storeModels.get(holder.getAdapterPosition()).current_location));
}
}
#Override
public int getItemCount() {
return stLstStores.size()+1;
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView res_name;
TextView res_rating;
TextView res_address;
TextView res_phone;
TextView res_distance;
TextView current_location;
ImageView res_image;
int view_type;
public MyViewHolder(View itemView,int viewType) {
super(itemView);
if(viewType == TYPE_LIST) {
view_type=1;
this.res_name = (TextView) itemView.findViewById(R.id.name);
this.res_rating = (TextView) itemView.findViewById(R.id.rating);
this.res_address = (TextView) itemView.findViewById(R.id.address);
this.res_phone = (TextView) itemView.findViewById(R.id.phone);
this.res_distance = (TextView) itemView.findViewById(R.id.distance);
this.res_image = (ImageView) itemView.findViewById(R.id.res_image);
}
else if(viewType == TYPE_HEAD){
view_type = 0;
this.current_location = (TextView) itemView.findViewById(R.id.location_tv);
}
}
}
}
Please note I will form the URL of the image by placing the photo reference, API key and width, I want to know how to show this image url in form of an image in image view
You can use Picasso for that;
ImageView thumbNail;
Picasso.with(MainActivity.this).load(photo_reference).noFade().into(thumbNail);
I am able to Save the JSON Data to the Realm Database. I have used as the documentation of the Realm, but I am not able to set the data to the GridView. I am using Custom Adapter not the Realm Adapter. The Data are Logged but they are not Displayed to the GridView. How can this the Data be Retrieved and Displayed to the GridView?
PopularDestinationGridDetail this is where JSON data is parsed and saved to database
Realm.init(this);
realm = Realm.getDefaultInstance();
LinearAddTOFavourite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
savetoDatabase();
}
});
public void savetoDatabase() {
realm.executeTransactionAsync(new Realm.Transaction() {
#Override
public void execute(Realm bgRealm) {
RealmDatabasePopularDestination realmDatabasePopularDestination = bgRealm.createObject(RealmDatabasePopularDestination.class);
realmDatabasePopularDestination.setTitle(title);
realmDatabasePopularDestination.setTitle(latitude);
realmDatabasePopularDestination.setTitle(longitude);
realmDatabasePopularDestination.setImage(image);
// Toast.makeText(this, realmDatabasePopularDestination.setLatitude(realmDatabasePopularDestination1.getLatitude()))
}
}, new Realm.Transaction.OnSuccess() {
#Override
public void onSuccess() {
Log.v("Success",title);
}
}, new Realm.Transaction.OnError() {
#Override
public void onError(Throwable error) {
Log.e("failed", error.getMessage());
}
});
}
Favourites
public class Favourites extends Fragment {
Realm realm;
GridView gridViewBookmark;
ArrayList<RealmDatabasePopularDestination> destination_bookmark_realm = new ArrayList<>();
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
Realm.init(getContext());
realm = Realm.getDefaultInstance();
RealmDatabasePopularDestination realmDatabasePopularDestination = new RealmDatabasePopularDestination();
View view = inflater.inflate(R.layout.bookmark_layout_gridview, container, false);
gridViewBookmark = (GridView) view.findViewById(R.id.gridviewBookmark);
destination_bookmark_realm.add(realmDatabasePopularDestination);
getData();
return view;
}
public void getData() {
FavouriteAdapter favouriteAdapter = new FavouriteAdapter(getContext(), destination_bookmark_realm);
gridViewBookmark.setAdapter(favouriteAdapter);
RealmResults<RealmDatabasePopularDestination> result = realm.where(RealmDatabasePopularDestination.class).equalTo("Title","niyash temple").findAll();
result.load();
System.out.println("Result is" + result);
// String output = "";
// for (RealmDatabasePopularDestination realmDatabasePopularDestination : result) {
//
//
// output += realmDatabasePopularDestination.toString();
//
// }
//
// System.out.println("output" + output);
// System.out.println("Total size=" + result.size());
}
}
getter and setter
public class RealmDatabasePopularDestination extends RealmObject {
String Title;
String Latitude;
String Longitude;
String image;
public String getTitle() {
return Title;
}
public void setTitle(String title) {
Title = title;
}
public String getLatitude() {
return Latitude;
}
public void setLatitude(String latitude) {
Latitude = latitude;
}
public String getLongitude() {
return Longitude;
}
public void setLongitude(String longitude) {
Longitude = longitude;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
}
FavouriteAdapter
public class FavouriteAdapter extends BaseAdapter {
Context mContext;
ArrayList<RealmDatabasePopularDestination> clas_realm_bookmark = null;
String TAG = "HomeTab_adapter";
public FavouriteAdapter(Context mContext, ArrayList<RealmDatabasePopularDestination> clas_realm_bookmark) {
super();
this.mContext = mContext;
this.clas_realm_bookmark = clas_realm_bookmark;
}
#Override
public int getCount() {
return clas_realm_bookmark.size();
}
#Override
public Object getItem(int position) {
return clas_realm_bookmark.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final FavouriteAdapter.Holder viewHolder;
if (convertView == null) {
// inflate the layout
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// LayoutInflater inflater = LayoutInflater.from(parent.getContext());
convertView = inflater.inflate(R.layout.bookmark_grid_list_item, parent, false);
// well set up the ViewHolder
// viewHolder = new ClassScheduleStudentAdapter.Holder();
viewHolder = new FavouriteAdapter.Holder();
// viewHolder.popular_destintion_id = (TextView) convertView.findViewById(R.id.student_profile_subject);
viewHolder.title = (TextView) convertView.findViewById(R.id.festivalName);
viewHolder.imageLogo = (ImageView) convertView.findViewById(R.id.event_festival_main_image);
// Log.d(TAG, "## postion:" + position + " getTeacherName" + class_destination.get(position).getId());
convertView.setTag(viewHolder);
} else {
// we've just avoided calling findViewById() on resource everytime
// just use the viewHolder
// viewHolder = (ClassScheduleStudentAdapter.Holder) convertView.getTag();
viewHolder = (Holder) convertView.getTag();
}
viewHolder.title.setText(clas_realm_bookmark.get(position).getTitle());
Picasso.with(mContext).load(clas_realm_bookmark.get(position).getImage()).error(R.drawable.close).into(viewHolder.imageLogo);
return convertView;
}
class Holder {
TextView title;
ImageView imageLogo;
}
}
I am not getting any error but they are not set on the ListView.This is the first time using realm, so don't get where I am doing wrong.
Instead of
public class FavouriteAdapter extends BaseAdapter {
Context mContext;
ArrayList<RealmDatabasePopularDestination> clas_realm_bookmark = null;
You should be using RealmBaseAdapter from realm-android-adapters as specified in the documentation.
you are setting adapter to list view before extracting data from database.
RealmResults<RealmDatabasePopularDestination> result = realm.where(RealmDatabasePopularDestination.class).equalTo("Title","niyash temple").findAll();
result.load();
FavouriteAdapter favouriteAdapter = new FavouriteAdapter(getContext(), destination_bookmark_realm);
gridViewBookmark.setAdapter(favouriteAdapter);
use above code and.
destination_bookmark_realm it should be load with the result you got from databse
I'm new in Android and I have following code that shows the list of item in Adapter.
I have Four Different Adapter from where I am calling one comman AsyncTask to update Result. I have implemented one Interface ApiResponse and overrides apiResponseProcessing() to get result.
In Item of List "Add to Cart" Button Added in every row. OnClick of that button I am requesting to server. On Success of that response i want to update Button with "Added To Cart".
I have question How to update that string which is binded in onBindViewHolder(). I am getting success in that method but dont know how to update clicked Button from that method.
Here's my Adapter
/**
* Adapter
**/
public class AlbumPhotoDetailAdapter
extends RecyclerView.Adapter<AlbumPhotoDetailAdapter.ViewHolder> implements ApiResponse {
private final ArrayList<Photo> mValues;
Album album;
private Activity mContext;
private int mMemberId;
public AlbumPhotoDetailAdapter(Activity context, ArrayList<Photo> items) {
mValues = items;
this.mContext = context;
mMemberId = MemberPreference.getMemberId(mContext);
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.album_photo_detail_sub_view, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
final Photo photo = mValues.get(position);
/**
* Album Owner Name
*/
String mOwnerName = photo.getOwnerName();
String mOwnerProfilePic = photo.getOwnerImage();
String mDateTime = photo.getDatetime();
String mPrice = String.valueOf(photo.getPrice());
/**
* Price String
*/
String priceStr = String.format(mContext.getString(R.string.string_dollar_price), mPrice);
holder.mAlbumPhotoDetailPhotoPrice.setText(priceStr);
/**
* Main Image
*/
Picasso.with(mContext).load(photo.getLink())
.error(R.drawable.ic_place_holder_circle)
.placeholder(R.drawable.ic_place_holder_circle)
.transform(new ImageTransformation(holder.mAlbumPhotoDetailSubMainImage))
.into(holder.mAlbumPhotoDetailSubMainImage);
/**
* Owner Name and Profile Pic
*/
holder.mAlbumPhotoDetailSubOwnerNameTextView.setText(mOwnerName);
Picasso.with(mContext).load(mOwnerProfilePic)
.error(R.drawable.ic_place_holder_circle)
.placeholder(R.drawable.ic_place_holder_circle)
.resize(100, 100)
.transform(new CircleTransform())
.into(holder.mAlbumPhotoDetailSubOwnerImage);
mDateTime = mDateTime != null ? DateUtils.getNiceTime(mDateTime) : "----";
holder.mAlbumPhotoDetailSubOwnerPostedTimeTextView.setText(mDateTime);
// Photo Add to cart.
holder.mAddToCartButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(InternetConnection.checkConnection(mContext)) {
new BackgroundAsyncTask(mContext, (ApiResponse) mContext, mMemberId, photo.getId()).execute();
} else {
DailyStudio.noInternetConnectionToast(mContext);
}
}
});
}
#Override
public int getItemCount() {
return mValues.size();
}
#Override
public void apiResponseProcessing(String response) {
Log.i(TAG,"Api Response : "+response);
if(response.equals(Fields.JSON_SUCCESS)) {
}
}
/**
* View Holder
*/
public static class ViewHolder extends RecyclerView.ViewHolder {
public final View mView;
private ImageView mAlbumPhotoDetailSubOwnerImage;
private ImageView mAlbumPhotoDetailSubMainImage;
private TextView mAlbumPhotoDetailSubOwnerNameTextView;
private TextView mAlbumPhotoDetailSubOwnerPostedTimeTextView;
private TextView mAlbumPhotoDetailPhotoPrice;
private TextView mAlbumPhotoDetailSubDescription;
private Button mAddToCartButton;
public ViewHolder(View view) {
super(view);
mView = view;
mAlbumPhotoDetailSubOwnerImage = (ImageView) view.findViewById(R.id.album_photo_detail_sub_owner_image);
mAlbumPhotoDetailSubMainImage = (ImageView) view.findViewById(R.id.album_photo_detail_sub_main_image);
mAlbumPhotoDetailSubOwnerNameTextView = (TextView) view.findViewById(R.id.album_photo_detail_sub_owner_name_text_view);
mAlbumPhotoDetailSubOwnerPostedTimeTextView = (TextView) view.findViewById(R.id.album_photo_detail_sub_owner_posted_time_text_view);
mAlbumPhotoDetailPhotoPrice = (TextView) view.findViewById(R.id.album_photo_detail_photo_price);
mAlbumPhotoDetailSubDescription = (TextView) view.findViewById(R.id.album_photo_detail_sub_description);
mAddToCartButton = (Button) view.findViewById(R.id.album_photo_detail_photo_add_to_cart_button);
}
}
}
Here's my Interface
/**
* Interface..
*/
public interface ApiResponse {
public void apiResponseProcessing(String response);
}
Here's my Background AsyncTask
/**
* Background AsyncTask...
*/
public class BackgroundAsyncTask extends AsyncTask<Void, Void, String> {
private Context context;
private String accessToken;
private int memberId;
private int photoId;
private ApiResponse objIBaseApi;
public BackgroundAsyncTask(Context context, ApiResponse apiResponse, int memberId, int photoId) {
this.context = context;
this.memberId = memberId;
this.photoId = photoId;
accessToken = MemberPreference.getAccessToken(context);
this.objIBaseApi = apiResponse;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(Void... params) {
JSONObject json = JSONParser.addToCartPhoto(accessToken, memberId, photoId);
if(json != null) {
Log.i(TAG,"First Json : "+json.toString());
try {
if (json.getString(Fields.RESULT).equalsIgnoreCase(Fields.JSON_SUCCESS)) {
return Fields.JSON_SUCCESS;
} else if(json.getString(Fields.JSON_ERROR).equalsIgnoreCase(Fields.ERROR_ACCESS_DENIED)) {
String refreshToken = MemberPreference.getRefreshToken(context);
JSONObject newJSONObject = JSONParser.loginMemberWithRefreshToken(refreshToken, Integer.toString(memberId));
if(newJSONObject != null) {
if(newJSONObject.getString(Fields.JSON_ERROR).equalsIgnoreCase(Fields.ERROR_ACCESS_DENIED)) {
return Fields.ERROR_ACCESS_DENIED;
} else {
return Fields.JSON_SUCCESS;
}
} else
return Fields.ERROR_ACCESS_DENIED;
} else {
return Fields.JSON_ERROR;
}
} catch (JSONException e) {
e.printStackTrace();
return Fields.JSON_ERROR;
}
}
return Fields.JSON_ERROR;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
objIBaseApi.apiResponseProcessing(result);
}
}
Is there any solution or better way to do like this?
Your help would be appreciated. Thank you.
You Can keep one flag isAddedToCart variable in you bean class which you are using in your adapter(Photo). Now just pass the position in your asynctask once user click on "add to cart" button. On getting the successful you just need to find the bean from the list of bean you passed in adapter and change the flag isAddedToCart to true and notify your adapter thats it. Here is the code snippet:-
Photo Class
public class Photo{
private boolean isAddedToCart;
public void setAddedTOCart(boolean isAdded){
isAddedToCart = isAdded;
}
public boolean isAddedToCart(){
return isAddedToCart;
}
}
AlbumPhotoDetailAdapter onBindViewHolder
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
final Photo photo = mValues.get(position);
/**
* Album Owner Name
*/
String mOwnerName = photo.getOwnerName();
String mOwnerProfilePic = photo.getOwnerImage();
String mDateTime = photo.getDatetime();
String mPrice = String.valueOf(photo.getPrice());
String isAdded = photo.isAddedToCart();
/**
* Price String
*/
String priceStr = String.format(mContext.getString(R.string.string_dollar_price), mPrice);
holder.mAlbumPhotoDetailPhotoPrice.setText(priceStr);
/**
* Main Image
*/
Picasso.with(mContext).load(photo.getLink())
.error(R.drawable.ic_place_holder_circle)
.placeholder(R.drawable.ic_place_holder_circle)
.transform(new ImageTransformation(holder.mAlbumPhotoDetailSubMainImage))
.into(holder.mAlbumPhotoDetailSubMainImage);
/**
* Owner Name and Profile Pic
*/
holder.mAlbumPhotoDetailSubOwnerNameTextView.setText(mOwnerName);
Picasso.with(mContext).load(mOwnerProfilePic)
.error(R.drawable.ic_place_holder_circle)
.placeholder(R.drawable.ic_place_holder_circle)
.resize(100, 100)
.transform(new CircleTransform())
.into(holder.mAlbumPhotoDetailSubOwnerImage);
mDateTime = mDateTime != null ? DateUtils.getNiceTime(mDateTime) : "----";
holder.mAlbumPhotoDetailSubOwnerPostedTimeTextView.setText(mDateTime);
if(isAdded){
holder.mAddToCartButton.setText("Added TO Cart");
}else{
holder.mAddToCartButton.setText("Add TO Cart");
}
// Photo Add to cart.
holder.mAddToCartButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(InternetConnection.checkConnection(mContext)) {
new BackgroundAsyncTask(mContext, (ApiResponse) mContext, mMemberId, photo.getId(),position).execute();
} else {
DailyStudio.noInternetConnectionToast(mContext);
}
}
});
}
your Interface
public interface ApiResponse {
public void apiResponseProcessing(String response,int position);
}
Your Adapter apiResponceProcessing()
#Override
public void apiResponseProcessing(String response,int position) {
Log.i(TAG,"Api Response : "+response);
if(response.equals(Fields.JSON_SUCCESS)) {
mValues.get(position).setAddedTOCart(true);
notifyDataSetChange();
}
}
And finally your
BackgroundAsyncTask
public class BackgroundAsyncTask extends AsyncTask<Void, Void, String> {
private Context context;
private String accessToken;
private int memberId;
private int photoId;
private int mPosition;
private ApiResponse objIBaseApi;
public BackgroundAsyncTask(Context context, ApiResponse apiResponse, int memberId, int photoId,int position) {
this.context = context;
this.memberId = memberId;
this.photoId = photoId;
accessToken = MemberPreference.getAccessToken(context);
this.objIBaseApi = apiResponse;
this.mPosition = position;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(Void... params) {
JSONObject json = JSONParser.addToCartPhoto(accessToken, memberId, photoId);
if(json != null) {
Log.i(TAG,"First Json : "+json.toString());
try {
if (json.getString(Fields.RESULT).equalsIgnoreCase(Fields.JSON_SUCCESS)) {
return Fields.JSON_SUCCESS;
} else if(json.getString(Fields.JSON_ERROR).equalsIgnoreCase(Fields.ERROR_ACCESS_DENIED)) {
String refreshToken = MemberPreference.getRefreshToken(context);
JSONObject newJSONObject = JSONParser.loginMemberWithRefreshToken(refreshToken, Integer.toString(memberId));
if(newJSONObject != null) {
if(newJSONObject.getString(Fields.JSON_ERROR).equalsIgnoreCase(Fields.ERROR_ACCESS_DENIED)) {
return Fields.ERROR_ACCESS_DENIED;
} else {
return Fields.JSON_SUCCESS;
}
} else
return Fields.ERROR_ACCESS_DENIED;
} else {
return Fields.JSON_ERROR;
}
} catch (JSONException e) {
e.printStackTrace();
return Fields.JSON_ERROR;
}
}
return Fields.JSON_ERROR;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
objIBaseApi.apiResponseProcessing(result,mPosition);
}
}
Firstly in my opinion adapter should not care about network request. But
giving an answer in substance, you can try pass anonymous class for your apiResponseProcessing in same manner as you create OnClickListener for your button. It can look like this:
holder.mAddToCartButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(InternetConnection.checkConnection(mContext)) {
new BackgroundAsyncTask(
mContext,
new ApiResponse() {
#Override
public void apiResponseProcessing(String response) {
Log.i(TAG,"Api Response : "+response);
if(response.equals(Fields.JSON_SUCCESS)) {
// Here you can access you holder till it final
}
}
},
mMemberId,
photo.getId()).execute();
} else {
DailyStudio.noInternetConnectionToast(mContext);
}
}
});
But code like this looks messy and spaghetti. As i say at the beginning there are exist at least one different approach to handle changes for buttons inside listview/recivleview. I use method, where adapter only care about building interface with given data and delegate buttons clicks to someone else (in most cases activity that contains listview). An easy way notify activity about button click is Bus messaging pattern. I use Otto event library. When delegate receive notification about button click, it can initiate data changing according current task and then initiate listview reloading or partial update only required rows.
Additional comments
Try to write beautiful code. Constructor AlbumPhotoDetailAdapter has different syntax to assign instance variables. One with this keyword and other without. Usually you should use one way.
public AlbumPhotoDetailAdapter(Activity context, ArrayList<Photo> items) {
this.values = items;
this.context = context;
this.memberId = MemberPreference.getMemberId(context);
}
album instance variable have no access modifiers indication. You should know, that in java programming language omitting access specifiers is not the same as private modifier.
How to show date or today , yesterday like text in between conversation
like whatsapp
MainActivity
public class MainActivity extends AppCompatActivity {
private ChatAdapter chatAdapter;
private RecyclerView recyclerView;
private Context context;
private int loggedInUserID;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
bindRecyclerView();
// TODO get logged in user id and initialize into 'loggedInUserID'
}
#Override
protected void onResume() {
super.onResume();
getData();
}
private void getData() {
/**
*Your server call to get data and parse json to your appropriate model
* after parsing json to model simply call the
*/
List<ChatModel> chatModelList = ParseData.chatParser(jsonArray);
groupDataIntoHashMap(chatModelList);
}
private void bindRecyclerView() {
chatAdapter = new ChatAdapter(null);
chatAdapter.setUser(loggedInUserID);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(context);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(chatAdapter);
}
private void groupDataIntoHashMap(List<ChatModel> chatModelList) {
LinkedHashMap<String, Set<ChatModel>> groupedHashMap = new LinkedHashMap<>();
Set<ChatModel> list = null;
for (ChatModel chatModel : chatModelList) {
//Log.d(TAG, travelActivityDTO.toString());
String hashMapKey = DateParser.convertDateToString(chatModel.getChatTime());
//Log.d(TAG, "start date: " + DateParser.convertDateToString(travelActivityDTO.getStartDate()));
if (groupedHashMap.containsKey(hashMapKey)) {
// The key is already in the HashMap; add the pojo object
// against the existing key.
groupedHashMap.get(hashMapKey).add(chatModel);
} else {
// The key is not there in the HashMap; create a new key-value pair
list = new LinkedHashSet<>();
list.add(chatModel);
groupedHashMap.put(hashMapKey, list);
}
}
//Generate list from map
generateListFromMap(groupedHashMap);
}
private List<ListObject> generateListFromMap(LinkedHashMap<String, Set<ChatModel>> groupedHashMap) {
// We linearly add every item into the consolidatedList.
List<ListObject> consolidatedList = new ArrayList<>();
for (String date : groupedHashMap.keySet()) {
DateObject dateItem = new DateObject();
dateItem.setDate(date);
consolidatedList.add(dateItem);
for (ChatModel chatModel : groupedHashMap.get(date)) {
ChatModelObject generalItem = new ChatModelObject();
generalItem.setChatModel(chatModel);
consolidatedList.add(generalItem);
}
}
chatAdapter.setDataChange(consolidatedList);
return consolidatedList;
}
}
ChatModel.java
public class ChatModel implements Serializable {
private String messageId;
private int userId;
private String firstName;
private String userName;
private String message;
private Date chatTime;
//TODO generate getter and setter
}
ListObject.java (to determind the type of message)
public abstract class ListObject {
public static final int TYPE_DATE = 0;
public static final int TYPE_GENERAL_RIGHT = 1;
public static final int TYPE_GENERAL_LEFT = 2;
abstract public int getType(int userId);
}
DateObject.java
public class DateObject extends ListObject {
private String date;
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
#Override
public int getType(int userId) {
return TYPE_DATE;
}
}
ChatModelObject.java
public class ChatModelObject extends ListObject {
private ChatModel chatModel;
public ChatModel getChatModel() {
return chatModel;
}
public void setChatModel(ChatModel chatModel) {
this.chatModel = chatModel;
}
#Override
public int getType(int userId) {
if (this.chatModel.getUserId() == userId) {
return TYPE_GENERAL_RIGHT;
} else
return TYPE_GENERAL_LEFT;
}
}
DateParse.java to parse date for grouping the chat
public class DateParser {
private static DateFormat dateFormat1 = new SimpleDateFormat("dd/MM/yyyy");
public static String convertDateToString(Date date) {
String strDate = "";
strDate = dateFormat1.format(date);
return strDate;
}
}
ChatAdapter.java
public class ChatAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<ListObject> listObjects;
private int loggedInUserId;
public ChatAdapter(List<ListObject> listObjects) {
this.listObjects = listObjects;
}
public void setUser(int userId) {
this.loggedInUserId = userId;
}
public void setDataChange(List<ListObject> asList) {
this.listObjects = asList;
//now, tell the adapter about the update
notifyDataSetChanged();
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder viewHolder = null;
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
switch (viewType) {
case ListObject.TYPE_GENERAL_RIGHT:
View currentUserView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_chat_list_row_right, parent, false);
viewHolder = new ChatRightViewHolder(currentUserView); // view holder for normal items
break;
case ListObject.TYPE_GENERAL_LEFT:
View otherUserView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_chat_list_row_left, parent, false);
viewHolder = new ChatLeftViewHolder(otherUserView); // view holder for normal items
break;
case ListObject.TYPE_DATE:
View v2 = inflater.inflate(R.layout.date_row, parent, false);
viewHolder = new DateViewHolder(v2);
break;
}
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
switch (viewHolder.getItemViewType()) {
case ListObject.TYPE_GENERAL_RIGHT:
ChatModelObject generalItem = (ChatModelObject) listObjects.get(position);
ChatRightViewHolder chatViewHolder = (ChatRightViewHolder) viewHolder;
chatViewHolder.bind(generalItem.getChatModel());
break;
case ListObject.TYPE_GENERAL_LEFT:
ChatModelObject generalItemLeft = (ChatModelObject) listObjects.get(position);
ChatLeftViewHolder chatLeftViewHolder = (ChatLeftViewHolder) viewHolder;
chatLeftViewHolder.bind(generalItemLeft.getChatModel());
break;
case ListObject.TYPE_DATE:
DateObject dateItem = (DateObject) listObjects.get(position);
DateViewHolder dateViewHolder = (DateViewHolder) viewHolder;
dateViewHolder.bind(dateItem.getDate());
break;
}
}
#Override
public int getItemCount() {
if (listObjects != null) {
return listObjects.size();
}
return 0;
}
#Override
public int getItemViewType(int position) {
return listObjects.get(position).getType(loggedInUserId);
}
public ListObject getItem(int position) {
return listObjects.get(position);
}
}
ChatRightViewHolder.java for current user message
public class ChatRightViewHolder extends RecyclerView.ViewHolder {
private final String TAG = ChatRightViewHolder.class.getSimpleName();
public ChatRightViewHolder(View itemView) {
super(itemView);
//TODO initialize your xml views
}
public void bind(final ChatModel chatModel) {
//TODO set data to xml view via textivew.setText();
}
}
ChatLeftViewHolder.java for display other user messages.
public class ChatLeftViewHolder extends RecyclerView.ViewHolder {
private final String TAG = ChatRightViewHolder.class.getSimpleName();
public ChatLeftViewHolder(View itemView) {
super(itemView);
//TODO initialize your xml views
}
public void bind(final ChatModel chatModel) {
//TODO set data to xml view via textivew.setText();
}
}
DateViewHolder.java to display date
public class DateViewHolder extends RecyclerView.ViewHolder {
public DateViewHolder(View itemView) {
super(itemView);
//TODO initialize your xml views
}
public void bind(final String date) {
//TODO set data to xml view via textivew.setText();
}
}
You need to create a new ViewHolder for that purpose
For example:
// Different types of rows
private static final int TYPE_ITEM_LEFT = 0;
private static final int TYPE_ITEM_RIGHT = 1;
private static final int TYPE_ITEM_DATE_CONTAINER = 2;
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
class ViewHolder0 extends RecyclerView.ViewHolder {
// Viewholder for row type 0
}
class ViewHolder1 extends RecyclerView.ViewHolder {
// Viewholder for row type 1
}
class ViewHolder2 extends RecyclerView.ViewHolder {
// Viewholder for row type 2
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder viewHolder, int position) {
if (viewHolder.getItemViewType() == TYPE_ITEM_LEFT) {
// Code to populate type 0 view here
} else if (viewHolder.getItemViewType() == TYPE_ITEM_RIGHT) {
// Code to populate type 1 view here
} else if (viewHolder.getItemViewType() == TYPE_ITEM_DATE_CONTAINER) {
// Code to populate type 2 view here
}
}
You just have to compare the date when scrolling and set the visibility of date view. The advantage of this is there's no hard-coded today/yesterday in data list and is able to refresh the correct date immediately (scrolling) after 12.00 a.m.
e.g. in your onBindViewHolder() in recycleview:
if (position != 0) {
processDate(holder.topDateTextView, myData.getDate()
, this.myDataList.get(position - 1).getDate()
, false)
;
} else {
processDate(holder.topDateTextView, data.getDay()
, null
, true)
;
}
Method to process that date view (Assume your list has format "dd/MM/yyyy"):
private void processDate(#NonNull TextView tv, String dateAPIStr
, String dateAPICompareStr
, boolean isFirstItem) {
SimpleDateFormat f = new SimpleDateFormat("dd/MM/yyyy");
if (isFirstItem) {
//first item always got date/today to shows
//and overkill to compare with next item flow
Date dateFromAPI = null;
try {
dateFromAPI = f.parse(dateAPIStr);
if (DateUtils.isToday(dateFromAPI.getTime())) tv.setText("today");
else if (DateUtils.isToday(dateFromAPI.getTime() + DateUtils.DAY_IN_MILLIS)) tv.setText("yesterday");
else tv.setText(dateAPIStr);
tv.setIncludeFontPadding(false);
tv.setVisibility(View.VISIBLE);
} catch (ParseException e) {
e.printStackTrace();
tv.setVisibility(View.GONE);
}
} else {
if (!dateAPIStr.equalsIgnoreCase(dateAPICompareStr)) {
try {
Date dateFromAPI = f.parse(dateAPIStr);
if (DateUtils.isToday(dateFromAPI.getTime())) tv.setText("today");
else if (DateUtils.isToday(dateFromAPI.getTime() + DateUtils.DAY_IN_MILLIS)) tv.setText("yesterday");
else tv.setText(dateAPIStr);
tv.setIncludeFontPadding(false);
tv.setVisibility(View.VISIBLE);
} catch (ParseException e) {
e.printStackTrace();
tv.setVisibility(View.GONE);
}
} else {
tv.setVisibility(View.GONE);
}
}
}
Note: You also need to do yourAdapter.notifyDataSetChanged(); if append new item to redraw to dismiss previous "today"/date after 12.00 a.m on the same page, not just rely on yourAdapter.notifyItemInserted(new_item_position) which doesn't redraw previous items.
I have three images stored in a table class called: "events" and table column called: "image" on Parse.com
I used two queries 1 to handle the displaying of the images and one to get another table's information (Those are all Strings)
THE PROBLEM IS:
The query that i used to get all the images only displays one of the three images in the RecyclerView instead of all three.
How can i display all three images from Parse.com inside a RecyclerView?
MY MAIN ACTIVITY:
public class MainActivity extends Activity {
//Defining Variables
protected Toolbar toolbar;
protected NavigationView navigationView;
private DrawerLayout drawerLayout;
protected Button mButtonHeader;
protected TextView mDayOfTheWeek;
protected TextView mDate;
//protected Context context;
//private long pageId = 137317903012386L;
private RecyclerView mRecyclerView;
//New Variables
private CustomAdapter mAdapter;
//Weather variables
//private ImageView weatherIconImageView;
private TextView temperatureTextView;
private TextView conditionTextView;
private TextView locationTextView;
private ProgressDialog dialog;
private ProgressDialog progressDialog;
final List<Information> data = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//RecyclerView with Parse
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view_layout);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mAdapter = new CustomAdapter(getApplicationContext(), data);
//The Query i used to get the three images
ParseQuery<ParseObject> queryImgs = new ParseQuery<ParseObject> ("events");
//queryImgs.orderByAscending("order");
//queryImgs.setLimit(10);
queryImgs.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(final List<ParseObject> objects, ParseException e) {
//for (ParseObject obj_food : objects) {
//if (obj_food.getInt("order") == order) {
for (int i = 0; i < objects.size(); i++) {
//final ParseFile file = obj_food.getParseFile("image");
//Information information = new Information();
//information.mEventsPhotoID = objects.get(i).getParseFile("image");
final ParseFile file = objects.get(i).getParseFile("image");
//bitmap
file.getDataInBackground(new GetDataCallback() {
public void done(byte[] data, ParseException e) {
if (e == null) {
Bitmap bmp = BitmapFactory
.decodeByteArray(
data, 0,
data.length);
// Get the ImageView from
// main.xml
mEventsPhotoID = (ParseImageView) findViewById(R.id.eventsPhotoID);
//mEventsPhotoIDTwo = (ParseImageView)findViewById(R.id.eventsPhotoID);
// Set the Bitmap into the
// ImageView
mEventsPhotoID.setImageBitmap(bmp);
//mEventsPhotoIDTwo.setImageBitmap(bmp);
}
}
});
//}
//order++;
}
mRecyclerView.setAdapter(mAdapter);
}
});
//Query to load String data into the card view/recycler view
ParseQuery<ParseObject> query = ParseQuery.getQuery("events");
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> objects, ParseException e) {
if (e == null) {
for (int i = 0; i < objects.size(); i++) {
Information information = new Information();
information.mNewstTitle = objects.get(i).getString("name");
information.mNewsStory = objects.get(i).getString("shortinfo");
//information.partyCost = parseObject.getString("partyName");
String url=objects.get(i).getParseFile("image").getUrl();
//information.mEventsPhotoID = objects.getParseFile("partyFlyerImage");
//information.mEventsPhotoID = objects.get(i).getParseFile("image");
//information.mNewsPhotoIcon = R.drawable.newsitem));
//Initialize ImageView
ParseImageView imageViewPicasso = (ParseImageView) findViewById(R.id.eventsPhotoID);
//Loading image from below url into imageView
Picasso.with(MainActivity.this)
.load(url)
.into(imageViewPicasso);
data.add(information);
}
} else {
// something went wrong
}
//adapter.notifyItemRangeInserted(startPosition, imageUrls.length);
mRecyclerView.setAdapter(mAdapter);
}
});
}//END onCreate
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
drawerLayout.openDrawer(GravityCompat.START);
return true;
}
return super.onOptionsItemSelected(item);
}
}//End Main Activity
MY ADAPTER CLASS:
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.MyViewHolder> {
//private List<String> imageUrls = new ArrayList<>();
List<Information> data = Collections.emptyList();
private LayoutInflater inflater;
private Context context;
/*public CustomAdapter (Context context,List<Information>data){
this.context=context;
inflater=LayoutInflater.from(context);
this.data= data;
}*/
public CustomAdapter (Context context,List<Information>data){
this.context=context;
inflater=LayoutInflater.from(context);
this.data= data;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
View view= inflater.inflate(R.layout.cardview_upcomingshows, parent, false);
MyViewHolder holder = new MyViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position){
Information current= data.get(position);
//holder.mEventsPhotoID.setImageResource(current.mEventsPhotoID);
holder.mNewstTitle.setText(current.mNewstTitle);
holder.mNewsStory.setText(current.mNewsStory);
holder.mEventsPhotoID.setParseFile(current.mEventsPhotoID);
//holder.mEventsPhotoIDTwo.setParseFile(current.mEventsPhotoIDTwo);
}
#Override
public int getItemCount(){
return data.size();
}
class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
//ImageView mEventsPhotoID;
TextView mNewstTitle;
TextView mNewsStory;
ParseImageView mEventsPhotoID;
//ParseImageView mEventsPhotoIDTwo;
public MyViewHolder(View itemView) {
super(itemView);
//promoterImage = (ParseImageView) itemView.findViewById(R.id.promoterPicImage);
mEventsPhotoID = (ParseImageView) itemView.findViewById(R.id.eventsPhotoID);
//mEventsPhotoIDTwo = (ParseImageView) itemView.findViewById(R.id.eventsPhotoIDTwo);
mNewstTitle = (TextView) itemView.findViewById(R.id.newsTitle);
mNewsStory = (TextView) itemView.findViewById(R.id.newsStory);
mNewstTitle.setOnClickListener(this);
mNewsStory.setOnClickListener(this);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
Toast.makeText(context, "Recycle Click" + getLayoutPosition(), Toast.LENGTH_SHORT).show();
if(getLayoutPosition()==0){
Intent intentEventsWebView = new Intent(itemView.getContext(), EventsWebViewActivity.class);
//intentIndependenceDay.putExtra("MyClass", myclass);
intentEventsWebView.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
itemView.getContext().startActivity(intentEventsWebView);
}
if(getLayoutPosition()==1){
Intent intentIndependenceDay = new Intent(itemView.getContext(), NextActivity.class);
//intentIndependenceDay.putExtra("MyClass", myclass);
intentIndependenceDay.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
itemView.getContext().startActivity(intentIndependenceDay);
}
if(getLayoutPosition()==2){
Intent intentShelleyMaxwellDance = new Intent(itemView.getContext(), OtherActivity.class);
//intentIndependenceDay.putExtra("MyClass", myclass);
intentShelleyMaxwellDance.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
itemView.getContext().startActivity(intentShelleyMaxwellDance);
}
}
}
}
MY DATA MODEL CLASS(CONTAINING DATA FOR THE RECYCLER VIEW):
public class Information {
String mNewstTitle;
String mNewsStory;
ParseFile mEventsPhotoID;
}
instead of reading the ParseFile yourself, try using the Url approach mentioned here:
Displaying ParseFile Containing Images Using Their Urls In A RecyclerView