I am trying to save an ArrayList of objects (List shelfItems) in the bundle to retrieve it next time the activity is opened.
(the activity gets info from firestore and I want to decrease reads and take away loading time each time the activity is opened).
but i get this error message:
savedInstanceState.putParcelableArrayList("key", shelfItems);
"putParcelableArrayList(java.lang.String, java.util.ArrayList)' in 'android.os.Bundle' cannot be applied to '(java.lang.String, java.util.List)"
This is my object class:
import android.os.Parcel;
import android.os.Parcelable;
public class ShelfItem implements Parcelable{
private String mTitle;
private String mAuthor;
private String mThumbnail;
private long mRating;
private long mEndDate;
private long mBeginDate;
private String mId;
private long mPages;
private boolean mVisible;
//make ShelfItem object
public ShelfItem(String title, String author, String thumbnail, long rating, long beginDate, long endDate, String id, long pages, boolean visible) {
mTitle = title;
mAuthor = author;
mThumbnail = thumbnail;
mRating = rating;
mBeginDate = beginDate;
mEndDate = endDate;
mId = id;
mPages = pages;
mVisible = visible;
}
public String getTitle() {
return mTitle;
}
public String getAuthor() {
return mAuthor;
}
public String getThumbnail() {
return mThumbnail;
}
public long getRating() {
return mRating;
}
public long getBeginDate() {
return mBeginDate;
}
public long getEndDate() {
return mEndDate;
}
public String getId() {
return mId;
}
public long getPages() {
return mPages;
}
public boolean getVisible() {
return mVisible;
}
public ShelfItem(Parcel in) {
mId = in.readString();
mTitle = in.readString();
mAuthor = in.readString();
mThumbnail = in.readString();
mBeginDate = in.readLong();
mEndDate = in.readLong();
mPages = in.readLong();
mVisible = in.readByte() != 0;
mRating = in.readLong();
}
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel out, int flags) {
out.writeString(mId);
out.writeString(mTitle);
out.writeString(mAuthor);
out.writeString(mThumbnail);
out.writeLong(mBeginDate);
out.writeLong(mEndDate);
out.writeLong(mPages);
out.writeByte((byte) (mVisible ? 1 : 0));
out.writeLong(mRating);
}
public static final Parcelable.Creator<ShelfItem> CREATOR = new Parcelable.Creator<ShelfItem>() {
public ShelfItem createFromParcel(Parcel in) {
return new ShelfItem(in);
}
public ShelfItem[] newArray(int size) {
return new ShelfItem[size];
}
};
}
and this is how I try to save the list:
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putParcelableArrayList("key", shelfItems);
}
As we learn Java, we're taught to use the interface type (List) instead of the implementation type (ArrayList) when we declare our variables. You probably have code somewhere that looks like this:
List<ShelfItem> shelfItems = new ArrayList<>();
However, in the particular case of Bundle and saving lists, you must use ArrayList specifically, and not any List in general.
If I'm right, and your list is declared like I've shown above, just change it to explicitly use ArrayList:
ArrayList<ShelfItem> shelfItems = new ArrayList<>();
If you're getting the list from somewhere else, and you can't control the implementation type of it, you can construct a new ArrayList when you need to save it:
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
ArrayList<ShelfItem> toSave = new ArrayList<>(shelfItems);
savedInstanceState.putParcelableArrayList("key", toSave);
}
Related
I am working on a video player app. I have two fragments: one is AllVideolist fragment and the other one is Videos folders fragment. The AllVideoListenter code here fragment is working fine, but I don't know how to show get all videos folder.
This is my MainActivity.java code.
MainActivity.java
public ArrayList<videoFiles> getAllVideos(Context context) {
ArrayList<videoFiles> tempArrayList = new ArrayList<>();
Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
String [] projection = {
MediaStore.Video.Media._ID,
MediaStore.Video.Media.DATA,
MediaStore.Video.Media.TITLE,
MediaStore.Video.Media.DISPLAY_NAME,
MediaStore.Video.Media.SIZE,
MediaStore.Video.Media.DATE_ADDED,
MediaStore.Video.Media.DURATION
};
Cursor cursor = context.getContentResolver().query(uri, projection, null, null, null);
if (cursor!= null){
while (cursor.moveToNext()){
String id =cursor.getString(0);
String path =cursor.getString(1);
String title =cursor.getString(2);
String fileName =cursor.getString(3);
String size =cursor.getString(4);
String dateAdded =cursor.getString(5);
String duration =cursor.getString(6);
int durationa = Integer.parseInt(duration);
String duration_formet;
int sec = (durationa/1000)%60;
int min = (durationa/(1000*60))%60;
int hours = durationa/(1000*60*60);
if (hours == 0){
duration_formet = String.valueOf(min).concat(":" .concat(String.format(Locale.UK, "%02d",sec)));
}else {
duration_formet = String.valueOf(hours).concat(":" .concat(String.format(Locale.UK, "%02d",min).concat(":" .concat(String.format(Locale.UK, "%02d",sec)))));
}
videoFiles videoFiles = new videoFiles(id, path, title,fileName,size, dateAdded,duration_formet);
Log.d("path", path);
tempArrayList.add(videoFiles);
}
cursor.close();
}
return tempArrayList;
}
I craete this model class.
VideoFiles.java
public class videoFiles {
///------------------MODEL CLASS ---------------
private String id;
private String path;
private String title;
private String fileName;
private String size;
private String dateAdded;
private String duration;
public videoFiles(String id, String path, String title, String fileName, String size, String dateAdded, String duration) {
this.id = id;
this.path = path;
this.title = title;
this.fileName = fileName;
this.size = size;
this.dateAdded = dateAdded;
this.duration = duration;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getSize() {
return size;
}
public void setSize(String size) {
this.size = size;
}
public String getDateAdded() {
return dateAdded;
}
public void setDateAdded(String dateAdded) {
this.dateAdded = dateAdded;
}
public String getDuration() {
return duration;
}
public void setDuration(String duration) {
this.duration = duration;
}
This is folder Adapter.
FolderAdapter.java
public class FolderAdapter extends RecyclerView.Adapter<FolderAdapter.folderViewHolder> {
View view;
Context context;
private ArrayList<videoFiles> folderList;
public FolderAdapter(Context context, ArrayList<videoFiles> folderList) {
this.context = context;
this.folderList = folderList;
}
#NonNull
#Override
public FolderAdapter.folderViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
view = LayoutInflater.from(context).inflate(R.layout.foldeitems, parent, false);
return new folderViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull FolderAdapter.folderViewHolder holder, int position) {
holder.folderName.setText(folderList.get(position).getPath());
}
#Override
public int getItemCount() {
return folderList.size();
}
public class folderViewHolder extends RecyclerView.ViewHolder {
TextView folderName;
public folderViewHolder(#NonNull View itemView) {
super(itemView);
folderName = itemView.findViewById(R.id.foldername);
}
}
}
This is main foledr fragment. I want to show videos in folder by folder
FoldeFragment.java
public class FolderFragment extends Fragment {
View view;
RecyclerView recyclerView;
public FolderFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view= inflater.inflate(R.layout.fragment_folder, container, false);
recyclerView = view.findViewById(R.id.folderRecylerView);
return view;
}
}
There is no "videos folder" in Android. There are number of default locations for videos, but they vary from device to device. Devices that have expandable memory often have video storage defaults that don't exist on non-expandable devices. User are not obliged to put video files in these default locations, anyway.
If you want to get a list of all directories that contain video files, you'll either need to implement some sort of search/index operation yourself, or use the built-in media database. You should be able to enumerate the list of videos from the database, and extract the unique folder names.
For what it's worth, I answered a similar question here:
How to show only videos folder?
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
Getting Error
FATAL EXCEPTION: main
Process: com.example.wuntu.tv_bucket, PID: 3895
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Integer.intValue()' on a null object reference
at com.example.wuntu.tv_bucket.Models.Cast.writeToParcel(Cast.java:136)
at android.os.Parcel.writeParcelable(Parcel.java:1437)
at android.os.Parcel.writeValue(Parcel.java:1343)
at android.os.Parcel.writeList(Parcel.java:759)
at android.os.Parcel.writeValue(Parcel.java:1365)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:686)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1330)
at android.os.Bundle.writeToParcel(Bundle.java:1079)
at android.os.Parcel.writeBundle(Parcel.java:711)
at android.content.Intent.writeToParcel(Intent.java:8790)
at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:3112)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1541)
at android.app.Activity.startActivityForResult(Activity.java:4284)
at android.support.v4.app.BaseFragmentActivityJB.startActivityForResult(BaseFragmentActivityJB.java:50)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:79)
at android.app.Activity.startActivityForResult(Activity.java:4231)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:859)
at android.app.Activity.startActivity(Activity.java:4568)
at android.app.Activity.startActivity(Activity.java:4536)
at com.example.wuntu.tv_bucket.Adapters.CastDetailAdapter$1.onClick(CastDetailAdapter.java:124)
at android.view.View.performClick(View.java:5698)
at android.widget.TextView.performClick(TextView.java:10908)
at android.view.View$PerformClick.run(View.java:22557)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7231)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Getting error in sending arraylist of object from adapter to other activity. I wanna send my arraylist from onBindViewHolder method of Adapter to another activity but its is showing null exception error on the Cast Class in writetoParcel Method. How to send arraylist properly?
Cast Class
public class Cast implements Parcelable {
#SerializedName("cast_id")
#Expose
private Integer castId;
#SerializedName("character")
#Expose
private String character;
#SerializedName("credit_id")
#Expose
private String creditId;
#SerializedName("gender")
#Expose
private Integer gender;
#SerializedName("id")
#Expose
private Integer id;
#SerializedName("name")
#Expose
private String name;
#SerializedName("order")
#Expose
private Integer order;
#SerializedName("profile_path")
#Expose
private String profilePath;
public Cast(){
}
protected Cast(Parcel in) {
character = in.readString();
id = in.readInt();
name = in.readString();
profilePath = in.readString();
}
public static final Creator<Cast> CREATOR = new Creator<Cast>() {
#Override
public Cast createFromParcel(Parcel in) {
return new Cast(in);
}
#Override
public Cast[] newArray(int size) {
return new Cast[size];
}
};
public Integer getCastId() {
return castId;
}
public void setCastId(Integer castId) {
this.castId = castId;
}
public String getCharacter() {
return character;
}
public void setCharacter(String character) {
this.character = character;
}
public String getCreditId() {
return creditId;
}
public void setCreditId(String creditId) {
this.creditId = creditId;
}
public Integer getGender() {
return gender;
}
public void setGender(Integer gender) {
this.gender = gender;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getOrder() {
return order;
}
public void setOrder(Integer order) {
this.order = order;
}
public String getProfilePath() {
return profilePath;
}
public void setProfilePath(String profilePath) {
this.profilePath = profilePath;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int i)
{
parcel.writeString(name);
parcel.writeString(profilePath);
parcel.writeString(character);
parcel.writeInt(id);
}
}
CastDetailAdapter Class
public class CastDetailAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private ArrayList<Cast> detailArrayList = new ArrayList<>() ;
private UrlConstants urlConstants = UrlConstants.getSingletonRef();
private Cast cast;
private final int VIEW_ITEM = 0;
private final int VIEW_PROG = 1;
private Context context;
MovieView a;
ArrayList<Cast> FullArrayList = new ArrayList<>();
public CastDetailAdapter(MovieView movieView, ArrayList<Cast> detailArrayList,ArrayList<Cast> subCastArrayList)
{
a = movieView;
this.detailArrayList = subCastArrayList;
this.FullArrayList = detailArrayList;
}
public class MyViewHolder1 extends RecyclerView.ViewHolder
{
ImageView cast_profile_picture;
TextView cast_name,cast_character_name;
public MyViewHolder1(View view)
{
super(view);
cast_profile_picture = (ImageView) view.findViewById(R.id.thumbnail);
cast_name = (TextView) view.findViewById(R.id.title);
cast_character_name = (TextView) view.findViewById(R.id.count);
}
}
public class FooterViewHolder1 extends RecyclerView.ViewHolder
{
TextView view_more;
public FooterViewHolder1(View itemView) {
super(itemView);
view_more = (TextView) itemView.findViewById(R.id.view_more);
}
}
#Override
public int getItemViewType(int position) {
if (isPositionItem(position))
return VIEW_ITEM;
return VIEW_PROG;
}
private boolean isPositionItem(int position) {
return position != getItemCount() -1;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
context = parent.getContext();
if (viewType == VIEW_ITEM)
{
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.cast_details, parent, false);
return new MyViewHolder1(v);
} else if (viewType == VIEW_PROG){
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.footer_layout_movie_details, parent, false);
return new FooterViewHolder1(v);
}
return null;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
if(holder instanceof MyViewHolder1)
{
cast = detailArrayList.get(position);
((MyViewHolder1)holder).cast_character_name.setText(cast.getCharacter());
((MyViewHolder1)holder).cast_name.setText(cast.getName());
String url3 = urlConstants.URL_Image + cast.getProfilePath();
Picasso.with(context)
.load(url3)
.into(((MyViewHolder1)holder).cast_profile_picture);
}
else if (holder instanceof FooterViewHolder1)
{
((FooterViewHolder1)holder).view_more.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view)
{
Intent intent = new Intent(context,CastViewActivity.class);
intent.putParcelableArrayListExtra("LIST",FullArrayList);
context.startActivity(intent);
}
});
}
}
#Override
public int getItemCount() {
return this.detailArrayList.size();
}
}
In your writeToParcel() method, you have
parcel.writeInt(id);
Since id is Integer, this is going to auto-unbox id. If id is null, this auto-unboxing will throw a NullPointerException.
Since there is no Parcel.writeInteger() method, you're going to have to record whether or not id is null in a separate write. Something like:
if (id == null) {
dest.writeInt(0);
}
else {
dest.writeInt(1);
dest.writeInt(id);
}
And to read it back out:
int hasId = in.readInt();
if (hasId == 1) {
id = in.readInt();
}
else {
id = null;
}
The order in which you read the values from the parcel has to be the same as the order it was written to it.
Try:
protected Cast(Parcel in) {
name = in.readString();
profilePath = in.readString();
character = in.readString();
id = in.readInt();
}
I am using Parcelable for a custom Song object I have in my class. However, when ever I am trying to get an arraylist extra of type Song I always get a null pointer exception. I have no problem getting string extras from the intent but when I try to get this ArrayList I need I always get null. I am also getting a null when I just try to pass a Song object, so I am assuming there is some issue with it but I cannot figure it out for the life of me.
This is my song class
import android.os.Parcel;
import android.os.Parcelable;
public class Song implements Parcelable {
private String uri;
private String title;
private String artist;
private String album;
private String length;
private int count;
private int source;
public Song () {
}
public Song (String title, String artist, String album, String uri, String length, int count,
int source) {
this.uri = uri;
this.title = title;
this.artist = artist;
this.album = album;
this.length = length;
this.count = count;
this.source = source;
}
public String getUri() {
return uri;
}
public String getArtist() {
return artist;
}
public String getTitle() {
return title;
}
public String getLength() {
return length;
}
public int getCount() {return count;}
#Override
public String toString() {
return title + " - " +artist;
}
#Override
public boolean equals(Object o){
if (o instanceof Song) {
Song song = (Song) o;
if (title.equals(song.title) && length.equals(song.length)) {
return true;
}
}
return false;
}
public int compareTo(Song s) {
if (this.count < s.getCount()) {
return -1;
}
else if(this.count > s.getCount()){
return 1;
}
return 0;
}
public String getAlbum() {
return album;
}
public void setAlbum(String album) {
this.album = album;
}
public int getSource() {
return source;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.uri);
dest.writeString(this.title);
dest.writeString(this.artist);
dest.writeString(this.album);
dest.writeString(this.length);
dest.writeInt(this.count);
dest.writeInt(this.source);
}
protected Song(Parcel in) {
this.uri = in.readString();
this.title = in.readString();
this.artist = in.readString();
this.album = in.readString();
this.length = in.readString();
this.count = in.readInt();
this.source = in.readInt();
}
public static final Creator<Song> CREATOR = new Creator<Song>() {
#Override
public Song createFromParcel(Parcel source) {
return new Song(source);
}
#Override
public Song[] newArray(int size) {
return new Song[size];
}
};
}
This is the line I use to package the arraylist
Intent intent = new Intent();
Log.d("UTILS ", " size: " +queue.size()); // Making sure it is not null before passing
intent.setClass(context, PlayerService.class);
intent.putParcelableArrayListExtra(PlayerService.EXTRA_TRACK_LIST, queue);
context.startService(intent);
This is retrieving the arraylist in PlayerService class
public static final String EXTRA_TRACK_LIST = "EXTRA_TRACK_LIST";
private ArrayList<Song> trackList;
.
.
.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent == null || intent.getAction() == null) {
Log.d(TAG, "unspecified command");
return START_STICKY;
}
trackList=intent.getParcelableArrayListExtra(PlayerService.EXTRA_TRACK_LIST);
if (trackList == null) {
Log.d("TRACKLIST", "IS NULL");
} else {
Log.d(TAG, "size: "+trackList.size());
}
.
.
.
// more irrelevant code
your parameter is wrong
public static final String EXTRA_TRACK_LIST = "EXTRA_TRACK_LIST";
so change like this
trackList = intent.getParcelableArrayListExtra(PlayerService.EXTRA_TRACK_LIST);
Is queue a Queue/List or similar? Or is it an array? If array, should be queue.length, right? From List to array try this. This should work.
intent.putParcelableArrayListExtra(PlayerService.EXTRA_TRACK_LIST, queue);
If not, let me know to keep trying. Also, you could also pass it as String. You could use GSON to convert it to JSON string. After converted to String, pass it as a single String.
Intent intent = new Intent(ActivityA.this, Service.class);
intent.putExtra(new Gson().toJson(queue), PlayerService.EXTRA_TRACK_LIST);
context.startService(intent);
And to retrieve that object again:
Song song = new Gson().fromJson(intent.getStringExtra(PlayerService.EXTRA_TRACK_LIST), Song.class);
Or, if list (I believe you case):
Type listType = new TypeToken<ArrayList<Song.class>>(){}.getType();
List<Song> songList = new Gson().fromJson(intent.getStringExtra(PlayerService.EXTRA_TRACK_LIST), listType);
I am crafting a non profit charity app. Despite I have checked many questions in stack and google, i could not solve the problem.
I have 3 classes:
- BaseCell implements Parcelable (Base class)
- Needy extends BaseCell
- UserBasket class which hold the list of all classes extend BaseCell
Problem
I am holding Needy classes with Arraylist in UserBasket class. When i send it to another activity, if i add 1 item to the UserBasket i am getting ridiculous result(Missing or wrong characters) and if i add more than 1 item then i am getting exception.
I need to deliver UserBasket class(list of needy items) to the payment activity so i can calculate the total price for charity and perform necessary actions.
public abstract class BaseCell implements Parcelable {
String imageUrl;
int percentageOfCollectedDonation;
String needyTitle;
String needyDescription;
protected String category;
protected int amountOfCollectedDonation=0;
protected int amountOfTargetDonation=0;
protected int amountOfDonater=0;
protected int drawableID;
protected String campaignCode;
protected int maxInstallmentNumber;
int price;
public String getCellType() {
return cellType;
}
protected String cellType ;
/**
* How many of this campaign purchased by user
* */
protected int userPurchaseAmount = 1;
protected BaseCell(String cellType)
{
this.cellType = cellType;
}
protected BaseCell(Parcel in)
{
drawableID = in.readInt();
price = in.readInt();
imageUrl = in.readString();
needyTitle = in.readString();
needyDescription = in.readString();
category = in.readString();
campaignCode = in.readString();
maxInstallmentNumber = in.readInt();
userPurchaseAmount = in.readInt();
}
public static final Parcelable.Creator<BaseCell> CREATOR = new Parcelable.Creator<BaseCell>() {
#Override
public BaseCell createFromParcel(Parcel in) {
String cellType = in.readString();
BaseCell baseCell = null;
if (cellType.equals("Needy"))
{
baseCell = (Needy)new Needy(in);
}else
if (cellType.equals("Qurban"))
{
baseCell = (Qurban)new Qurban(in);
}
return baseCell;
}
#Override
public BaseCell[] newArray(int size) {
return new BaseCell[size];
}
};
public void writeToParcel(Parcel out, int flags) {
out.writeString(getCellType());
}
public BaseCell(String imageUrl, int drawableID, String needyTitle, String needyDescription, int amountOfCollectedDonation, int amountOfTargetDonation, int amountOfDonater, String category,String campaignCode, int maxInstallmentNumber, int price)
{
this.imageUrl = imageUrl;
this.drawableID = drawableID;
this.needyTitle = needyTitle;
this.needyDescription = needyDescription;
this.amountOfCollectedDonation = amountOfCollectedDonation;
this.amountOfTargetDonation = amountOfTargetDonation;
this.amountOfDonater = amountOfDonater;
this.category = category;
this.campaignCode = campaignCode;
this.maxInstallmentNumber = maxInstallmentNumber;
this.price= price;
}
}
Needy
public class Needy extends BaseCell {
protected Needy(Parcel in) {
super(in);
cellType ="Needy";
}
public static final Parcelable.Creator<Needy> CREATOR = new Parcelable.Creator<Needy>() {
#Override
public Needy createFromParcel(Parcel in) {
return new Needy(in);
}
#Override
public Needy[] newArray(int size) {
return new Needy[size];
}
};
public Needy(String imageUrl, int drawableID, String needyTitle, String needyDescription, int amountOfCollectedDonation, int amountOfTargetDonation, int amountOfDonater, String category, String campaignCode, int maxInstallmentNumber, int price) {
super(imageUrl, drawableID, needyTitle, needyDescription, amountOfCollectedDonation, amountOfTargetDonation, amountOfDonater, category, campaignCode, maxInstallmentNumber,price);
cellType = "Needy";
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(getCellType());
super.writeToParcel(dest,flags);
dest.writeInt(drawableID);
dest.writeInt(price);
dest.writeString(imageUrl);
dest.writeString(needyTitle);
dest.writeString(needyDescription);
dest.writeString(category);
dest.writeString(campaignCode);
dest.writeInt(maxInstallmentNumber);
dest.writeInt(userPurchaseAmount);
}
#Override
public void setUserPurchaseAmount(int userPurchaseAmount) {
super.setUserPurchaseAmount(userPurchaseAmount);
}
}
UserBasket
public class UserBasket implements Parcelable{
List<BaseCell> userBasket;
/**
* holds all items to be purchased
* */
public UserBasket(List<BaseCell> userBasket) {
this.userBasket = userBasket;
}
public UserBasket() {
userBasket = new ArrayList<>();
}
protected UserBasket(Parcel in) {
super();
setUserBasket(new ArrayList<BaseCell>());
userBasket = in.createTypedArrayList(BaseCell.CREATOR);
//in.readTypedList(userBasket,BaseCell.CREATOR);
}
public static final Parcelable.Creator<UserBasket> CREATOR = new Parcelable.Creator<UserBasket>() {
#Override
public UserBasket createFromParcel(Parcel in) {
return new UserBasket(in);
}
#Override
public UserBasket[] newArray(int size) {
return new UserBasket[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeTypedList(userBasket);
}
public List<BaseCell> getUserBasket() {
return userBasket;
}
public void setUserBasket(List<BaseCell> userBasket) {
this.userBasket = userBasket;
}
/**
* Add to the basket list
* */
public void add(Needy donation) {
if (donation != null)
userBasket.add(donation);
}
/**
* Remove from basket list
* */
public void remove(int position)
{
if (userBasket.size()>0)
userBasket.remove(position);
}
}
sending userBasket arrayList with items from MainActivity
Navigate.navigateToPaymentPayuStart
(MainActivity.this,userBasket,"basket");
// userBasket arrayList with "basket" key
Receiving UserBasket in paymentPayu activity
UserBasket userBasket = getIntent().getParcelableExtra("basket");
How am i going to get UserBasket properly in paymentPayuActivity.
I appreciate for the help
Thank you.
It does seem like you are handling the Parcelable implementation wrong. e.i. you are reading some of the variables from the Parcel twice, which isn't allowed. So to improve this, we'll try to make your code a bit simpler. As Needy doesn't actually have any variables, it seems better to let BaseCell handle all of the parcelable implementation, i've tried to create a mock for you, so depending on the rest of your code it might need a bit of tweaking.
First i've removed all of the Parcelable implementation in Needy and is just pointing it's CREATOR to BaseCell.
public class Needy extends BaseCell {
protected Needy(Parcel in) {
super(in);
cellType ="Needy";
}
// Since Needy doesn't actually store any variables, we don't need a Creator for it.
// Just point it to BaseCell.CREATOR and let it handle it
public static final Parcelable.Creator<BaseCell> CREATOR = BaseCell.CREATOR;
public Needy(String imageUrl, int drawableID, String needyTitle, String needyDescription, int amountOfCollectedDonation, int amountOfTargetDonation, int amountOfDonater, String category, String campaignCode, int maxInstallmentNumber, int price) {
super(imageUrl, drawableID, needyTitle, needyDescription, amountOfCollectedDonation, amountOfTargetDonation, amountOfDonater, category, campaignCode, maxInstallmentNumber,price);
cellType = "Needy";
}
}
And then we'll let BaseCell handle all of the Parcelable implementation, like so:
public abstract class BaseCell implements Parcelable {
/**
* ALL OF YOUR VARIABLES, GETTERS, SETTERS AND CONSTRUCTORS GOES HERE
*/
#Override
public int describeContents() {
return 0;
}
public static final Parcelable.Creator<BaseCell> CREATOR = new Parcelable.Creator<BaseCell>() {
#Override
public BaseCell createFromParcel(Parcel in) {
String cellType = in.readString();
if (cellType.equals("Needy")) {
return (Needy)new Needy(in);
} else if (cellType.equals("Qurban")) {
return (Qurban)new Qurban(in);
}
return null;
}
#Override
public BaseCell[] newArray(int size) {
return new BaseCell[size];
}
};
protected BaseCell(Parcel in) {
drawableID = in.readInt();
price = in.readInt();
imageUrl = in.readString();
needyTitle = in.readString();
needyDescription = in.readString();
category = in.readString();
campaignCode = in.readString();
maxInstallmentNumber = in.readInt();
userPurchaseAmount = in.readInt();
}
public void writeToParcel(Parcel out, int flags) {
// cellType written first, and read by Creator
out.writeString(cellType);
// the rest is read by the BaseCell constructor
out.writeInt(drawableID);
out.writeInt(price);
out.writeString(imageUrl);
out.writeString(needyTitle);
out.writeString(needyDescription);
out.writeString(category);
out.writeString(campaignCode);
out.writeInt(maxInstallmentNumber);
out.writeInt(userPurchaseAmount);
}
}
I'm using GSON to parse a JSON feed like this here:
http://dvz.hj.cx/api/get_recent_posts/?dev=1
My model class looks like this one here:
public class Recent {
#Expose
private String status;
#Expose
private int count;
#Expose
private int count_total;
#Expose
private int pages;
#Expose
private List<Post> posts = new ArrayList<Post>();
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Recent withStatus(String status) {
this.status = status;
return this;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public Recent withCount(int count) {
this.count = count;
return this;
}
public int getCount_total() {
return count_total;
}
public void setCount_total(int count_total) {
this.count_total = count_total;
}
public Recent withCount_total(int count_total) {
this.count_total = count_total;
return this;
}
public int getPages() {
return pages;
}
public void setPages(int pages) {
this.pages = pages;
}
public Recent withPages(int pages) {
this.pages = pages;
return this;
}
public List<Post> getPosts() {
return posts;
}
public void setPosts(List<Post> posts) {
this.posts = posts;
}
public Recent withPosts(List<Post> posts) {
this.posts = posts;
return this;
}
}
As you can see I'm referring to another model class called Post.
The Post model class looks like this one:
public class Post {
#Expose
private int id;
#Expose
private String url;
#Expose
private String title;
#Expose
private String date;
#Expose
private List<Category> categories = new ArrayList<Category>();
#Expose
private List<Object> tags = new ArrayList<Object>();
#Expose
private Author author;
#Expose
private List<Attachment> attachments = new ArrayList<Attachment>();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Post withId(int id) {
this.id = id;
return this;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Post withUrl(String url) {
this.url = url;
return this;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Post withTitle(String title) {
this.title = title;
return this;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public Post withDate(String date) {
this.date = date;
return this;
}
public List<Category> getCategories() {
return categories;
}
public void setCategories(List<Category> categories) {
this.categories = categories;
}
public Post withCategories(List<Category> categories) {
this.categories = categories;
return this;
}
public Author getAuthor() {
return author;
}
public void setAuthor(Author author) {
this.author = author;
}
public Post withAuthor(Author author) {
this.author = author;
return this;
}
public List<Attachment> getAttachments() {
return attachments;
}
public void setAttachments(List<Attachment> attachments) {
this.attachments = attachments;
}
public Post withAttachments(List<Attachment> attachments) {
this.attachments = attachments;
return this;
}
}
And again I'm reffering to some other models. Until now erverything works perfect, but now I need to access some of this getters and setters in my BaseAdapter.
My Adapter classe looks like this:
public class NewsList extends BaseAdapter {
private List<Recent> listData;
private LayoutInflater layoutInflater;
private Context mContext;
public ImageLoader imageLoader;
public NewsList(Context context, List<Recent> listData) {
this.listData = listData;
layoutInflater = LayoutInflater.from(context);
mContext = context;
imageLoader = new ImageLoader(context);
}
#Override
public int getCount() {
return listData.size();
}
#Override
public Object getItem(int position) {
return listData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.news_row_layout, null);
holder = new ViewHolder();
holder.headlineView = (TextView) convertView.findViewById(R.id.title);
holder.commentView = (TextView) convertView.findViewById(R.id.comment);
holder.reportedDateView = (TextView) convertView.findViewById(R.id.date);
holder.imageView = (ImageView) convertView.findViewById(R.id.thumbImage);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Recent rec = (Recent) listData.get(position);
Post post = (Post) rec.getPosts();
Attachment att = (Attachment) post.getAttachments();
List<Images> img = att.getImages();
Thumbnail thumb = (Thumbnail) img.getThumbnail();
Author author = (Author) post.getAuthor();
if(post != null){
/* date and time */
String date = post.getDate().replace("-",".");
String zeit = date.substring(11,16);
String datum = date.substring(0, 11);
String djahr = datum.substring(0,4);
String dmonat = datum.substring(5,8);
String dtag = datum.substring(8,10);
holder.headlineView.setText(Html.fromHtml(post.getTitle()));
holder.reportedDateView.setText(Html.fromHtml("Am <b>" + dtag+"."+dmonat+djahr+" </b>um <b>"+zeit+"</b>"));
holder.commentView.setText(Html.fromHtml("Von: <b>" + author.getName()));
ImageView image = holder.imageView;
if(post.attachments.getMime_type().contains("image")){
imageLoader.DisplayImage(thumb.getUrl(), image);
}
}
return convertView;
}
static class ViewHolder {
TextView headlineView;
TextView commentView;
TextView reportedDateView;
ImageView imageView;
}
}
As you see I try to get the List<Post> which is located inside the ArrayList<Recent>.
This line works perfect:
Recent rec = (Recent) listData.get(position);
But as soon as it comes to this line it doesn't work:
Post post = (Post) rec.getPosts();
I have no idea how to resolve this. Please help its very important for me. If you have a better solution, its welcome.
When it comes to this line Post post = (Post) rec.getPosts();, LogCat says
Cannot convert ArrayList to List
You are misinterpreting List<T> with T and this same problem is present at different parts of your code:
getPosts() returns List<Post> not Post like getImages() returns List<Images> not Images, you might need a loop to iterate over your List<Post>, getting single Post and then getting its data like List<Attachment>.
Change it to the following:
Recent rec = (Recent) listData.get(position);
List<Post> posts = rec.getPosts();
for(int i = 0; i < posts.size(); i++){
Post post = (Post) posts.get(i);
if(post != null){
List<Attachment> atts = post.getAttachments();
Attachment att = (Attachment) atts.get(0) // You can use loop instead of get(0)
List<Images> imgs = att.getImages();
Images img = (Images) imgs.get(0); // You can use loop instead of get(0)
Thumbnail thumb = (Thumbnail) img.getThumbnail();
Author author = (Author) post.getAuthor();
...
}
}