UnsupportedOperationException is thrown when removing item from RecyclerView using ItemTouchHelper - java

When item is removed from studentList throws:
**java.lang.UnsupportedOperationException
at java.util.AbstractList.remove(AbstractList.java:161)
at com.sayedy.naweed.test.newtest.TestCase$2.onSwiped**
I implemented ItemTouchHelper.Callback as will but leads to same exception.
I can swap studentList items using onMove() without any problem why can't delete item using onSwiped()?
RecyclerView:
public class TestCase extends RecyclerView.Adapter<TestCase.PassedViewHolder> {
private Context context;
private List<Student> studentList;
private ItemTouchHelper itemTouchHelper;
public TestCase(Context context, List<Student> studentList) {
this.context = context;
this.studentList = studentList;
}
public void setItemTouchHelper(ItemTouchHelper itemTouchHelper) {
this.itemTouchHelper = itemTouchHelper;
}
#NonNull
#Override
public PassedViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
StudentPassedRowBinding rowBinding = DataBindingUtil.inflate(
LayoutInflater.from(context),
R.layout.student_passed_row,
parent, false);
return new PassedViewHolder(rowBinding.getRoot());
}
#Override
public void onBindViewHolder(#NonNull PassedViewHolder holder, int position) {
holder.passedRowBinding.setStudent(studentList.get(position));
holder.passedRowBinding.getRoot().setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
itemTouchHelper.startDrag(holder);
return false;
}
});
}
#Override
public int getItemCount() {
return studentList.size();
}
class PassedViewHolder extends RecyclerView.ViewHolder {
public StudentPassedRowBinding passedRowBinding;
public PassedViewHolder(#NonNull View itemView) {
super(itemView);
passedRowBinding = DataBindingUtil.bind(itemView);
}
}
public ItemTouchHelper.SimpleCallback simpleCallback = new ItemTouchHelper.SimpleCallback(ItemTouchHelper.DOWN | ItemTouchHelper.UP, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, #NonNull RecyclerView.ViewHolder target) {
int currentPosition = viewHolder.getAdapterPosition();
int targetPosition = target.getAdapterPosition();
Collections.swap(studentList, currentPosition,targetPosition);
notifyItemMoved(currentPosition, targetPosition);
return true;
}
#Override
public void onSwiped(#NonNull RecyclerView.ViewHolder viewHolder, int direction) {
studentList.remove(viewHolder.getAdapterPosition());
notifyItemRemoved(viewHolder.getAdapterPosition());
}
};
}
The fragment initializes RecyclerView:
public View onCreateView(#NonNull LayoutInflater inflater,
#Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
studentBinding = FragmentStudentBinding.inflate(inflater);
// Data
List<Student> students = Arrays.asList(
new Student("Ahmad", 1, R.drawable.profile, "PASS"),
new Student("Mahmood", 2, R.drawable.profile, "FAIL"),
new Student("Zakir", 3, R.drawable.profile, "PASS"),
new Student("Rezaq", 8, R.drawable.profile, "FAIL"),
new Student("Zeya", 9, R.drawable.profile, "FAIL"),
new Student("Rasool", 10, R.drawable.profile, "FAIL"),
new Student("Parwiz", 11, R.drawable.profile, "FAIL"));
TestCase testCase = new TestCase(getContext(), students);
studentBinding.studentRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
studentBinding.studentRecyclerView.setAdapter(testCase);
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(testCase.simpleCallback);
testCase.setItemTouchHelper(itemTouchHelper);
itemTouchHelper.attachToRecyclerView(studentBinding.studentRecyclerView);
return studentBinding.getRoot();
}
Student class:
public class Student implements Parcelable {
private String name;
private int id;
private int studentProfile;
private String result;
public Student(String name, int id, int studentProfile, String result) {
this.name = name;
this.id = id;
this.studentProfile = studentProfile;
this.result = result;
}
protected Student(Parcel in) {
name = in.readString();
id = in.readInt();
studentProfile = in.readInt();
result = in.readString();
}
public static final Creator<Student> CREATOR = new Creator<Student>() {
#Override
public Student createFromParcel(Parcel in) {
return new Student(in);
}
#Override
public Student[] newArray(int size) {
return new Student[size];
}
};
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getStudentProfile() {
return studentProfile;
}
public void setStudentProfile(int studentProfile) {
this.studentProfile = studentProfile;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(id);
dest.writeInt(studentProfile);
dest.writeString(result);
}
}

I solved the problem.
The Arrays.asList() return a fixed-size list.
This list allow you to do operations like get and set, but the add and remove operations will throw UnsupportedOperationException.

Related

Nested RecycleView with Firebase this error "Expected a List while deserializing, but got a class java.util.HashMap" when I insert data using push()

This is the code for the nested recycler view.
If I add data using the push() method, i get the Nested RecycleView with Firebase this error:
Expected a List while deserializing, but got a class java.util.HashMap
AlertDialog dialog;
IFirebaseLoadListener iFirebaseLoadListener;
RecyclerView my_recycler_view;
DatabaseReference myData;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myData= FirebaseDatabase.getInstance().getReference("MyData");
dialog= new SpotsDialog.Builder().setContext(this).build();
iFirebaseLoadListener = this;
// view
my_recycler_view= (RecyclerView)findViewById(R.id.my_recycler_view);
my_recycler_view.setHasFixedSize(true);
my_recycler_view.setLayoutManager(new LinearLayoutManager(this));
load data
getFirebaseData();
}
private void getFirebaseData() {
dialog.show();
myData.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
List<itemGroup> itemGroups= new ArrayList<>();
for(DataSnapshot groupSnapshot: dataSnapshot.getChildren())
{
itemGroup itemGroup= new itemGroup();
///
Firebase instance code
///
itemGroup.setHeaderTitle(groupSnapshot.child("headerTitle").getValue(true).toString());
GenericTypeIndicator<ArrayList<itemData>> genericTypeIndicator= new GenericTypeIndicator<ArrayList<itemData>>(){} ;
itemGroup.setListItem(groupSnapshot.child("listItem").child(key).getValue(genericTypeIndicator));
itemGroups.add(itemGroup);
}
iFirebaseLoadListener.onFirebaseLoadSuccess(itemGroups);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
iFirebaseLoadListener.onFirebaseLoadFailed(databaseError.getMessage());
}
});
}
#Override
public void onFirebaseLoadSuccess(List<itemGroup> itemGroupList) {
MyItemGroupAdapter adapter = new MyItemGroupAdapter(this,itemGroupList);
my_recycler_view.setAdapter(adapter);
dialog.dismiss();
}
#Override
public void onFirebaseLoadFailed(String message) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
dialog.dismiss();
}
}
public class itemData {
private String name ,image;
public itemData() {
}
public itemData(String name, String image) {
this.name = name;
this.image = image;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
}
public class itemGroup {
private String headerTitle;
private ArrayList<itemData> listItem;
public itemGroup() {
}
public itemGroup(String headerTitle, ArrayList<itemData> listItem) {
this.headerTitle = headerTitle;
this.listItem = listItem;
}
public String getHeaderTitle() {
return headerTitle;
}
public void setHeaderTitle(String headerTitle) {
this.headerTitle = headerTitle;
}
public ArrayList<itemData> getListItem() {
return listItem;
}
public void setListItem(ArrayList<itemData> listItem) {
this.listItem = listItem;
}
}
public class MyItemAdapter extends RecyclerView.Adapter<MyItemAdapter.MyViewHolder> {
private Context context;
private List<itemData> itemDataList;
public MyItemAdapter(Context context, List<itemData> itemDataList) {
this.context = context;
this.itemDataList = itemDataList;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View itemView =
LayoutInflater.from(context).inflate(R.layout.layout_item,viewGroup,false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder myViewHolder, int i) {
myViewHolder.txt_item_titles.setText(itemDataList.get(i).getName());
Picasso.get().load(itemDataList.get(i).getImage()).into(myViewHolder.img_item);
myViewHolder.setiItemClickListener(new IItemClickListener() {
#Override
public void onItemClickListener(View view, int i) {
Toast.makeText(context, ""+ itemDataList.get(i).getName(),
Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {
return (itemDataList != null ? itemDataList.size() : 0);
}
public class MyViewHolder extends RecyclerView.ViewHolder implements
View.OnClickListener {
TextView txt_item_titles;
ImageView img_item;
IItemClickListener iItemClickListener;
public void setiItemClickListener(IItemClickListener iItemClickListener) {
this.iItemClickListener = iItemClickListener;
}
public MyViewHolder (View itemView ){
super(itemView);
txt_item_titles= (TextView)itemView.findViewById(R.id.tvTitle);
img_item= (ImageView) itemView.findViewById(R.id.itemImage);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
iItemClickListener.onItemClickListener(v,getAdapterPosition());
}
}
}
public class MyItemGroupAdapter extends
RecyclerView.Adapter<MyItemGroupAdapter.MyViewHolder> {
private Context context;
private List<itemGroup> dataList;
public MyItemGroupAdapter(Context context, List<itemGroup> dataList) {
this.context = context;
this.dataList = dataList;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View itemView =
LayoutInflater.from(context).inflate(R.layout.layout_group,viewGroup,false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull final MyViewHolder myViewHolder, int i) {
myViewHolder.item_title.setText(dataList.get(i).getHeaderTitle());
List<itemData> itemData = dataList.get(i).getListItem();
MyItemAdapter itemListAdapter=new MyItemAdapter(context,itemData);
myViewHolder.recycler_view_item_list.setHasFixedSize(true);
myViewHolder.recycler_view_item_list.setLayoutManager(new
LinearLayoutManager(context,LinearLayoutManager.HORIZONTAL,false));
myViewHolder.recycler_view_item_list.setAdapter(itemListAdapter);
myViewHolder.recycler_view_item_list.setNestedScrollingEnabled(false);
// btn more
myViewHolder.btn_more.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context, "Button More "+ myViewHolder.item_title.getText(),
Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {
return (dataList != null ? dataList.size() : 0);
}
public class MyViewHolder extends RecyclerView.ViewHolder{
TextView item_title ;
RecyclerView recycler_view_item_list;
Button btn_more;
public MyViewHolder (View itemView ){
super (itemView);
item_title= (TextView) itemView.findViewById(R.id.itemTitle);
btn_more= (Button)itemView.findViewById(R.id.btMore);
recycler_view_item_list=
(RecyclerView)itemView.findViewById(R.id.recycler_view_list);
}
}
}
This happens when you try to have a structure like this in the database:
"list": {
"-Nasdueqriyew": "First value",
"-Nberqiy39esd": "Second value",
"-Nc3hadsiuhad": "Third value"
}
And then try to map it to a List or array in your Java class.
The JSON structure is not a list, because it was pairs of keys and values, which in Java translates to:
Map<String, Object>
So most likely, the List<itemData> in your code needs to be a Map<String, itemData>.

Gridview item set based on matrix position [row][column]

I need to design the bus seat view in android application and I have seat positions in matrix format. For example
a1.row=4;
a1.column=5;
I only need to set those seats in gridview based on their matrix position. Other spaces will be blank or empty in matrix. After showing these seat view if I choose specific seat then that seat related object will be added in a list of object and if I deselect it will be removed from the list of object. Can anyone help me to find out a solution for this ? Is it possible to implement this using gridview but I will set the item in grid view using its matrix position
Try this code
Activityclass
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.rv_list);
showSeatList();
}
private void showSeatList()
{
List<SeatModel> seatModels = new ArrayList<>();
seatModels.add(new SeatModel("1","A",false));
seatModels.add(new SeatModel("2","B",false));
seatModels.add(new SeatModel("3","C",false));
seatModels.add(new SeatModel("4","D",false));
seatModels.add(new SeatModel("5","E",false));
seatModels.add(new SeatModel("6","F",false));
seatModels.add(new SeatModel("7","G",false));
seatModels.add(new SeatModel("8","H",false));
seatModels.add(new SeatModel("9","I",false));
seatModels.add(new SeatModel("10","J",false));
SeatSelectionAdapter adapter = new SeatSelectionAdapter(this,seatModels);
recyclerView.setLayoutManager(new GridLayoutManager(this, 5));
recyclerView.setAdapter(adapter);
}
}
Adapter Class
public class SeatSelectionAdapter extends RecyclerView.Adapter<SeatSelectionAdapter.ViewHolder>
{
private List<SeatModel> seatModelList;
private LayoutInflater inflater;
private Context context;
public SeatSelectionAdapter(Context context, List<SeatModel>models)
{
this.seatModelList = models;
inflater = LayoutInflater.from(context);
this.context = context;
}
#NonNull
#Override
public SeatSelectionAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.model_seat,parent,false);
return new SeatSelectionAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull SeatSelectionAdapter.ViewHolder holder, int position) {
SeatModel model = seatModelList.get(position);
holder.setData(model);
}
#Override
public int getItemCount() {
return seatModelList.size();
}
class ViewHolder extends RecyclerView.ViewHolder
{
private CardView cardView;
private LinearLayout lnLayout;
private TextView tvSeat;
private ViewHolder(View view) {
super(view);
tvSeat = view.findViewById(R.id.tv_seat);
cardView = view.findViewById(R.id.cv_card);
lnLayout = view.findViewById(R.id.ln_layout);
}
#SuppressLint({"SetTextI18n", "ClickableViewAccessibility"})
private void setData(final SeatModel model)
{
tvSeat.setText(model.getSeat());
if(model.isSelect())
lnLayout.setBackgroundColor(context.getResources().getColor(R.color.colorAccent));
else lnLayout.setBackgroundColor(context.getResources().getColor(R.color.white));
cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(model.isSelect())
{
model.setSelect(false);
Toast.makeText(context,"Seat not selected",Toast.LENGTH_LONG).show();
}
else{
model.setSelect(true);
Toast.makeText(context,"Seat selected",Toast.LENGTH_LONG).show();
}
notifyDataSetChanged();
}
});
}
}
}
Model Class
public class SeatModel
{
private String id,seat;
private boolean isSelect;
public SeatModel(String id, String seat, boolean isSelect) {
this.id = id;
this.seat = seat;
this.isSelect = isSelect;
}
public boolean isSelect() {
return isSelect;
}
public void setSelect(boolean select) {
isSelect = select;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getSeat() {
return seat;
}
public void setSeat(String seat) {
this.seat = seat;
}
}

STRIKE_THRU_TEXT_FLAG not working as Expected

This is my RecyclerView Adaptor Class
public class TodoAdaptor extends RecyclerView.Adapter<TodoAdaptor.SingleTodoView> {
private CheckBox checkbox;
private TextView title, dueDate;
private Context context;
private ArrayList<SingleTodo> todoList;
private onItemCLickListener itemCLickListener;
public TodoAdaptor(Context context, ArrayList<SingleTodo> todoList, onItemCLickListener onItemClickListener) {
this.context = context;
this.todoList = todoList;
this.itemCLickListener = onItemClickListener;
}
#NonNull
#Override
public SingleTodoView onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_todo, parent, false);
return new SingleTodoView(v, itemCLickListener);
}
#Override
public void onBindViewHolder(#NonNull SingleTodoView holder, int position) {
SingleTodo singleTodo = todoList.get(position);
checkbox.setChecked(singleTodo.isComplete());
title.setText(singleTodo.getTitle());
if (singleTodo.isComplete()) {
title.setPaintFlags(title.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
Toast.makeText(context, "IsCompleted", Toast.LENGTH_SHORT).show();
} else {
title.setPaintFlags(title.getPaintFlags() & (~Paint.STRIKE_THRU_TEXT_FLAG));
Toast.makeText(context, "Not IsCompleted", Toast.LENGTH_SHORT).show();
}
if (singleTodo.getDueDate().isEmpty()) {
dueDate.setVisibility(View.GONE);
} else {
dueDate.setText(singleTodo.getDueDate());
}
}
#Override
public int getItemCount() {
return todoList.size();
}
class SingleTodoView extends RecyclerView.ViewHolder {
private SingleTodoView(#NonNull View itemView, final onItemCLickListener itemCLickListener) {
super(itemView);
checkbox = itemView.findViewById(R.id.todo_list_completed_checkbox);
title = itemView.findViewById(R.id.todo_list_title);
dueDate = itemView.findViewById(R.id.todo_list_due_date);
title.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
itemCLickListener.onTextClickListener(getAdapterPosition());
}
});
checkbox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
itemCLickListener.onCheckboxClickListener(getAdapterPosition());
}
});
}
}
public interface onItemCLickListener {
void onTextClickListener(int position);
void onCheckboxClickListener(int position);
}
}
This is My Adaptor
todoAdaptor = new TodoAdaptor(this, singleTodoArrayList, new TodoAdaptor.onItemCLickListener() {
#Override
public void onTextClickListener(int position) {
singleTodo = singleTodoArrayList.get(position);
singleTodo.setTitle("This is Test");
singleTodoArrayList.set(position, singleTodo);
todoAdaptor.notifyItemChanged(position);
}
#Override
public void onCheckboxClickListener(int position) {
singleTodo = singleTodoArrayList.get(position);
singleTodo.setComplete(!singleTodo.isComplete());
singleTodoArrayList.set(position, singleTodo);
todoAdaptor.notifyItemChanged(position);
}
});
and This is my SingleTodo Class
package com.example.simpletodo.classes;
public class SingleTodo {
private int id;
private String title;
private String dueDate;
private boolean isComplete;
public SingleTodo(int id, String title, String dueDate, boolean isComplete) {
this.id = id;
this.title = title;
this.dueDate = dueDate;
this.isComplete = isComplete;
}
public int getId() {
return id;
}
public String getTitle() {
return title;
}
public String getDueDate() {
return dueDate;
}
public boolean isComplete() {
return isComplete;
}
public void setId(int id) {
this.id = id;
}
public void setTitle(String title) {
this.title = title;
}
public void setDueDate(String dueDate) {
this.dueDate = dueDate;
}
public void setComplete(boolean complete) {
isComplete = complete;
}
}
Whenever I check the checkbox, Text of that item should paint Strikethrough and Its not working as Expected
I have 3 Items in the list, when i click checkbox Item get Checked and Text Strikethrough works but when i again click checkbox checkbox stay checked (although Object is being Updated as it should be) and strikethrought text revert to normal, and i have to click checkbox twice again for check box to get unchecked
other issue is that when i checked on item and then i try to check other item, Current Item text get replaced by one of the other checked item Text.
Images :
Default:
When i click the Checkbox Once:
When i Click the Checkbox Again:
When i Checked multiple Items one by one(I have not changed position of any item before checking they was in default order and after checking --in order-- this is what i get)
Any Help is Appreciated. I just want my code to work as Expected.
I found the Solution from this Question
I had to change my Adaptor Class. I Declared Views inside my view holder class and onBindViewHolder, i am using first parameter (holder) to get my Views
public class TodoAdaptor extends RecyclerView.Adapter<TodoAdaptor.SingleTodoView> {
private boolean darkTheme;
private Context context;
private ArrayList<SingleTodo> todoList;
private onItemCLickListener itemCLickListener;
public TodoAdaptor(Context context, ArrayList<SingleTodo> todoList, boolean darkTheme, onItemCLickListener onItemClickListener) {
this.darkTheme = darkTheme;
this.context = context;
this.todoList = todoList;
this.itemCLickListener = onItemClickListener;
}
#NonNull
#Override
public SingleTodoView onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(context).inflate(R.layout.single_todo, parent, false);
return new SingleTodoView(v, itemCLickListener);
}
#Override
public void onBindViewHolder(#NonNull SingleTodoView holder, int position) {
SingleTodo singleTodo = todoList.get(position);
holder.checkbox.setChecked(singleTodo.isComplete());
holder.title.setText(singleTodo.getTitle());
if (singleTodo.isComplete()) {
holder.title.setPaintFlags(holder.title.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
} else {
holder.title.setPaintFlags(holder.title.getPaintFlags() & (~Paint.STRIKE_THRU_TEXT_FLAG));
}
if (singleTodo.getDueDate().isEmpty()) {
holder.dueDate.setVisibility(View.GONE);
} else {
holder.dueDate.setVisibility(View.VISIBLE);
holder.dueDate.setText(singleTodo.getDueDate());
}
}
#Override
public int getItemCount() {
return todoList.size();
}
class SingleTodoView extends RecyclerView.ViewHolder {
private CheckBox checkbox;
private TextView title, dueDate;
private SingleTodoView(#NonNull View itemView, final onItemCLickListener itemCLickListener) {
super(itemView);
checkbox = itemView.findViewById(R.id.todo_list_completed_checkbox);
title = itemView.findViewById(R.id.todo_list_title);
dueDate = itemView.findViewById(R.id.todo_list_due_date);
if (darkTheme) {
title.setTextColor(context.getResources().getColor(R.color.colorLightGray));
dueDate.setTextColor(context.getResources().getColor(R.color.colorLightGray));
} else {
title.setTextColor(context.getResources().getColor(R.color.colorBlack));
dueDate.setTextColor(context.getResources().getColor(R.color.colorBlack));
}
title.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
itemCLickListener.onTextClickListener(getAdapterPosition());
}
});
checkbox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
itemCLickListener.onCheckboxClickListener(getAdapterPosition());
}
});
}
}
public interface onItemCLickListener {
void onTextClickListener(int position);
void onCheckboxClickListener(int position);
}
}

How to send data of the list item of a custom arraylist when clicked to another activity?

I have an array list of custom Song objects and I want to send the song name, artist name and the album cover image to another activity (Song Activity) when a particular song item of the listview is clicked. I have created a SongActivity for showing the now playing screen for the song that the user has selected.
(SONGS LIST ACTIVITY) This contains the songs list.
public class SongsListActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.songs_list);
ArrayList<Song> songs = new ArrayList<Song>();
songs.add(new Song("Earthquake","Marshmello and TYNAN",R.mipmap.earthquake));
.....
final SongAdapter adapter = new SongAdapter(this, songs);
ListView listView = findViewById(R.id.list);
listView.setAdapter(adapter);
ListView listview = (ListView) findViewById(R.id.list);
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(view.getContext(), SongActivity.class);
}
});
}
}
(SONG ACTIVITY) This activity starts when a particular song object is clicked by the user
import androidx.appcompat.app.AppCompatActivity;
public class SongActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.song_activity);
ImageView songImage = findViewById(R.id.songImage);
TextView songName = findViewById(R.id.songName);
TextView artistName = findViewById(R.id.artistName);
Intent intent = getIntent();
songImage.setImageResource(intent.getIntExtra("image",0));
songName.setText(intent.getStringExtra("songName"));
artistName.setText(intent.getStringExtra("artistName"));
}
}
(SONG ADAPTER)
public class SongAdapter extends ArrayAdapter {
public SongAdapter(Activity context, ArrayList<Song> songs) {
super(context, 0, songs);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Check if the existing view is being reused, otherwise inflate the view
View listItemView = convertView;
if(listItemView == null) {
listItemView = LayoutInflater.from(getContext()).inflate(
R.layout.list_item, parent, false);
}
Song currentSong = (Song) getItem(position);
TextView nameTextView = (TextView) listItemView.findViewById(R.id.song_name);
nameTextView.setText(currentSong.getSongName());
TextView artistTextView = (TextView) listItemView.findViewById(R.id.artist_name);
artistTextView.setText(currentSong.getArtistName());
ImageView iconView = (ImageView) listItemView.findViewById(R.id.song_icon);
iconView.setImageResource(currentSong.getImageResourceId());
return listItemView;
}
}
Paracelize your modal like this
public class Student implements Parcelable {
private Integer rollno;
private String name;
private Integer age;
protected Student(Parcel in) {
age = in.readInt();
name = in.readString();
rollno = in.readInt();
}
public Student(Integer age, String name, Integer rollno) {
this.age = age;
this.name = name;
this.rollno = rollno;
}
public static final Creator<Student> CREATOR = new Creator<Student>() {
#Override
public Student createFromParcel(Parcel in) {
return new Student(in);
}
#Override
public Student[] newArray(int size) {
return new Student[size];
}
};
#Override
public int describeContents() {
return 0;
}
public Integer getRollno() {
return rollno;
}
public void setRollno(Integer rollno) {
this.rollno = rollno;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public static Creator<Student> getCREATOR() {
return CREATOR;
}
#Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeInt(age);
parcel.writeString(name);
parcel.writeInt(rollno);
}
}
And then set and get using intent
intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, studentList)
intents.getParcelableArrayList<Student>(Intent.EXTRA_STREAM)
Your Song Model(Class) Should look like this
import android.os.Parcel;
import android.os.Parcelable;
public final class Songs implements Parcelable {
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
#Override
public Songs createFromParcel(final Parcel source) {
return new Songs(source);
}
#Override
public Songs[] newArray(final int size) {
return new Songs[size];
}
};
private String songName;
private String artistName;
private Integer imageId;
public Songs() {
}
public Songs(final String songName, final String artistName, final Integer imageId) {
this.songName = songName;
this.artistName = artistName;
this.imageId = imageId;
}
protected Songs(final Parcel in) {
this.songName = in.readString();
this.artistName = in.readString();
this.imageId = (Integer) in.readValue(Integer.class.getClassLoader());
}
public String getSongName() {
return songName;
}
public void setSongName(final String songName) {
this.songName = songName;
}
public String getArtistName() {
return artistName;
}
public void setArtistName(final String artistName) {
this.artistName = artistName;
}
public Integer getImageId() {
return imageId;
}
public void setImageId(final Integer imageId) {
this.imageId = imageId;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(final Parcel dest, final int flags) {
dest.writeString(this.songName);
dest.writeString(this.artistName);
dest.writeValue(this.imageId);
}
}
In your SongListActivity
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView parent, View view, int position, long id) {
Intent intent = new Intent(view.getContext(), SongActivity.class);
intent.putExtra("SONG_DATA", songList.get(position));
startActivity(intent);
}
});
And at last in onCreate() of your SongActivity you have to get the intent and get the data like
if (getIntent() != null) {
Song song = getIntent().getParcelableExtra("SONG_DATA");
// now you have got song object, You can do rest of operations
}

I want to display an image from drawable and combine it with data from json-api into recylerview

I have an application project for news media using java programming, I
want to display images for categories from drawable into recylerview
that are based on json-api, is there any one who can help me?
How I do for load image from drawable and combine it with data from json-api into RecylerView can anyone provide specific code here
this is my AdapterCategory.java
public class AdapterCategory extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<Category> items = new ArrayList<>();
private Context ctx;
private OnItemClickListener mOnItemClickListener;
private int c;
public interface OnItemClickListener {
void onItemClick(View view, Category obj, int position);
}
public void setOnItemClickListener(final OnItemClickListener mItemClickListener) {
this.mOnItemClickListener = mItemClickListener;
}
// Provide a suitable constructor (depends on the kind of dataset)
public AdapterCategory(Context context, List<Category> items) {
this.items = items;
ctx = context;
}
public class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView name;
public TextView post_count;
public LinearLayout lyt_parent;
public ImageView imageView;
public ViewHolder(View v) {
super(v);
name = (TextView) v.findViewById(R.id.name);
post_count = (TextView) v.findViewById(R.id.post_count);
imageView = (ImageView)v.findViewById(R.id.image_category);
lyt_parent = (LinearLayout) v.findViewById(R.id.lyt_parent);
//imageView.setImageResource(image_array.length);
}
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_category, parent, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
if(holder instanceof ViewHolder) {
final Category c = items.get(position);
ViewHolder vItem = (ViewHolder) holder;
vItem.name.setText(Html.fromHtml(c.title));
vItem.post_count.setText(c.post_count + "");
Picasso.with(ctx).load(imageUri).into(vItem.imageView);
vItem.lyt_parent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (mOnItemClickListener != null) {
mOnItemClickListener.onItemClick(view, c, position);
}
}
});
}
}
public void setListData(List<Category> items){
this.items = items;
notifyDataSetChanged();
}
public void resetListData() {
this.items = new ArrayList<>();
notifyDataSetChanged();
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return items.size();
}
}
This is my FragmentCategory.java for display data
public class FragmentCategory extends Fragment {
private View root_view, parent_view;
private RecyclerView recyclerView;
private SwipeRefreshLayout swipe_refresh;
private AdapterCategory mAdapter;
private Call<CallbackCategories> callbackCall = null;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
root_view = inflater.inflate(R.layout.fragment_category, null);
parent_view = getActivity().findViewById(R.id.main_content);
swipe_refresh = (SwipeRefreshLayout) root_view.findViewById(R.id.swipe_refresh_layout_category);
recyclerView = (RecyclerView) root_view.findViewById(R.id.recyclerViewCategory);
recyclerView.setLayoutManager(new GridLayoutManager(getActivity(),3));
recyclerView.setHasFixedSize(true);
//set data and list adapter
mAdapter = new AdapterCategory(getActivity(), new ArrayList<Category>());
recyclerView.setAdapter(mAdapter);
// on item list clicked
mAdapter.setOnItemClickListener(new AdapterCategory.OnItemClickListener() {
#Override
public void onItemClick(View v, Category obj, int position) {
ActivityCategoryDetails.navigate((ActivityMain) getActivity(), v.findViewById(R.id.lyt_parent), obj);
}
});
// on swipe list
swipe_refresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
mAdapter.resetListData();
requestAction();
}
});
requestAction();
return root_view;
}
private void displayApiResult(final List<Category> categories) {
mAdapter.setListData(categories);
swipeProgress(false);
if (categories.size() == 0) {
showNoItemView(true);
}
}
private void requestCategoriesApi() {
API api = RestAdapter.createAPI();
callbackCall = api.getAllCategories();
callbackCall.enqueue(new Callback<CallbackCategories>() {
#Override
public void onResponse(Call<CallbackCategories> call, Response<CallbackCategories> response) {
CallbackCategories resp = response.body();
if (resp != null && resp.status.equals("ok")) {
displayApiResult(resp.categories);
} else {
onFailRequest();
}
}
#Override
public void onFailure(Call<CallbackCategories> call, Throwable t) {
if (!call.isCanceled()) onFailRequest();
}
});
}
private void onFailRequest() {
swipeProgress(false);
if (NetworkCheck.isConnect(getActivity())) {
showFailedView(true, getString(R.string.failed_text));
} else {
showFailedView(true, getString(R.string.no_internet_text));
}
}
private void requestAction() {
showFailedView(false, "");
swipeProgress(true);
showNoItemView(false);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
requestCategoriesApi();
}
}, Constant.DELAY_TIME);
}
#Override
public void onDestroy() {
super.onDestroy();
swipeProgress(false);
if(callbackCall != null && callbackCall.isExecuted()){
callbackCall.cancel();
}
}
private void showFailedView(boolean flag, String message) {
View lyt_failed = (View) root_view.findViewById(R.id.lyt_failed_category);
((TextView) root_view.findViewById(R.id.failed_message)).setText(message);
if (flag) {
recyclerView.setVisibility(View.GONE);
lyt_failed.setVisibility(View.VISIBLE);
} else {
recyclerView.setVisibility(View.VISIBLE);
lyt_failed.setVisibility(View.GONE);
}
((Button) root_view.findViewById(R.id.failed_retry)).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
requestAction();
}
});
}
private void showNoItemView(boolean show) {
View lyt_no_item = (View) root_view.findViewById(R.id.lyt_no_item_category);
((TextView) root_view.findViewById(R.id.no_item_message)).setText(R.string.no_category);
if (show) {
recyclerView.setVisibility(View.GONE);
lyt_no_item.setVisibility(View.VISIBLE);
} else {
recyclerView.setVisibility(View.VISIBLE);
lyt_no_item.setVisibility(View.GONE);
}
}
private void swipeProgress(final boolean show) {
if (!show) {
swipe_refresh.setRefreshing(show);
return;
}
swipe_refresh.post(new Runnable() {
#Override
public void run() {
swipe_refresh.setRefreshing(show);
}
});
}
And this is my ModeCategory.java
public class Category implements Serializable {
public int id = -1;
public String slug = "";
public String type = "";
public String url = "";
public String title = "";
public String title_plain = "";
public String content = "";
public String excerpt = "";
public String date = "";
public String modified = "";
public String description = "";
public int parent = -1;
public int post_count = -1;
public Author author;
public List<Category> categories = new ArrayList<>();
public List<Comment> comments = new ArrayList<>();
public List<Attachment> attachments = new ArrayList<>();
public CategoryRealm getObjectRealm(){
CategoryRealm c = new CategoryRealm();
c.id = id;
c.url = url;
c.slug = slug;
c.title = title;
c.description = description;
c.parent = parent;
c.post_count = post_count;
return c;
}
}

Categories

Resources