As the title says, I'm trying to add an item from a different class. I get no errors but the item doesn't appear. I've read about updating the recyclerview but I'm still not sure how to do this. Below is the code.
The home page is where the list will be shown and the floating action button will redirect the user to the add item page. Here the user will enter the name, price, description, etc. After pressing the button to add the item, it redirects the user back to the home page and the list should update.
Home.java
public class Home extends AppCompatActivity{
private FirebaseAuth mAuth;
private FloatingActionButton addItemFab;
private RecyclerView recyclerView;
// The adapter is responsible for loading the items in the recycler view we need. This ensures good performance
private RecyclerView.Adapter adapter;
// The layout manager is responsible for laying out the items in the Recycler view
private RecyclerView.LayoutManager layoutManager;
private ArrayList<Item> itemList;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.home_activity);
// Initialize Firebase Auth
mAuth = FirebaseAuth.getInstance();
// floating action button to add an item page
addItemFab = findViewById(R.id.addItemFab);
addItemFab.setOnClickListener(view -> {
Intent intent = new Intent(Home.this, AddItem.class);
startActivity(intent);
});
itemList = new ArrayList<Item>();
// add item for testing
itemList.add(new Item(R.drawable.ic_logo, "Baby Stroller", "A stroller for baby", "59.99"));
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
adapter = new Adapter(itemList);
adapter.notifyItemInserted(itemList.size()-1);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
}
// log out back to start page
public void goToStart(View view){
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
}
}
Adapter.java
public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder>{
private ArrayList<Item> ItemList;
public static class ViewHolder extends RecyclerView.ViewHolder{
public ImageView item_image;
public TextView item_name;
public TextView item_desc;
public TextView item_price;
public ViewHolder(#NonNull View itemView) {
super(itemView);
item_image = itemView.findViewById(R.id.item_image);
item_name = itemView.findViewById(R.id.item_name);
item_desc = itemView.findViewById(R.id.desc);
item_price = itemView.findViewById(R.id.price);
}
}
public Adapter(ArrayList<Item> itemList) {ItemList = itemList;}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_items, parent, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
Item currentItem = ItemList.get(position);
holder.item_image.setImageResource(currentItem.getItemImage());
holder.item_name.setText(currentItem.getItemName());
holder.item_desc.setText(currentItem.getItemDesc());
holder.item_price.setText(currentItem.getItemPrice());
}
#Override
public int getItemCount() {
return ItemList.size();
}
}
Item.java
public class Item {
private int itemImage;
private String itemName;
private String itemDesc;
private String itemPrice;
public Item(int itemImage, String itemName, String itemDesc, String itemPrice){
this.itemImage = itemImage;
this.itemName = itemName;
this.itemDesc = itemDesc;
this.itemPrice = itemPrice;
}
public int getItemImage(){return itemImage;}
public String getItemName(){return itemName;}
public String getItemDesc(){return itemDesc;}
public String getItemPrice(){return itemPrice;}
}
AddItem.java
public class AddItem extends AppCompatActivity {
ImageView itemImage;
EditText itemName;
EditText itemPrice;
EditText itemDesc;
private ArrayList<Item> itemList;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.add_item_activity);
itemImage = findViewById(R.id.image_holder);
itemName = findViewById(R.id.add_item_name);
itemPrice = findViewById(R.id.add_price);
itemDesc = findViewById(R.id.add_desc);
itemList = new ArrayList<Item>();
}
public void addItem(View view) {
itemList.add(new Item(R.drawable.ic_logo, itemName.getText().toString(), itemPrice.getText().toString(), itemDesc.getText().toString()));
Intent intent = new Intent(this, Home.class);
startActivity(intent);
}
}
Thanks for the help.
You should not be updating itemList in AddItem because this array have nothing to do whith the list of your recyclerView, what you should do instead is :
Start the AddActivity -> let the user create the Item object -> return the object to the HomeActivity and update your recyclerView there
To do that you can use StartActivityForResult by declaring it in your homeActivity and launch it in FAB:
ActivityResultLauncher<Intent> mStartForResult =
registerForActivityResult(new
ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == Activity.RESULT_OK) {
Intent intent = result.getData();
Item item = (Item) intent.getParcelableExtra("myItem");
adapter.addItem(item);
}
});
#Override
protected void onCreate(Bundle savedInstanceState) {
...
addItemFab.setOnClickListener(view -> {
Intent intent = new Intent(Home.this, AddItem.class);
startActivity(intent);
});
}
With the method addItem in your adapter as :
public void addItem(Item item){
ItemList.add(item)
this.notifyDataSetChanged()
}
And you would send back your item in AddItem like that :
public void addItem(View view) {
Item newItem = new Item(R.drawable.ic_logo, itemName.getText().toString(), itemPrice.getText().toString(), itemDesc.getText().toString());
Intent resultIntent = new Intent();
resultIntent.putExtra("myItem", newItem);
setResult(RESULT_OK, resultIntent);
finish();
}
Your Item should implement Parcelable to be able to be accepted in the intent
You can read more about how to communicate between activity here : https://developer.android.com/training/basics/intents/result
And more about Recycler view here : https://developer.android.com/develop/ui/views/layout/recyclerview
Related
I have a a view where a bunch of my Sqlite data is displayed. I recently added a column to my database called location_position. I have added a button to my relative layout so that when its clicked I want the data inside to be sorted in ascending format. I have tried following a few examples online but with the way my app is setup im struggling tom get it to work.
I have a routeView.java class and a routeAdapter
I would really apreciate if someone can show me how to have the content sorted when the button is clicked, or any resources with similar solutions
public class RouteView extends AppCompatActivity {
RecyclerView recyclerView;
routeAdapter routeAdapter;
ArrayList<String> location_id, location_name, location_county, location_description, location_route, location_position;
MyDatabaseHelper myDB;
Button createPDFButton, btnNorth, southBtn;
Context mContext = this;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_route_view);
Button southBtn = findViewById(R.id.button_south);
southBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Collections.sort(ArrayList);
}
});
// btnRemove = findViewById(R.id.btnRemove);
recyclerView = findViewById(R.id.recyclerView);
myDB = new MyDatabaseHelper(this);
createPDFButton = findViewById(R.id.createPDFButton);
location_id = new ArrayList<>();
location_name = new ArrayList<>();
location_county = new ArrayList<>();
location_description = new ArrayList<>();
location_route = new ArrayList<>();
location_position = new ArrayList<>();
Cursor cursor = myDB.readAllData();
createPDFButton.setOnClickListener(new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
#Override
public void onClick(View v) {
if (UserActivity.checkAppPermission(RouteView.this, "android.permission.WRITE_EXTERNAL_STORAGE", 1)){
generatePDF(recyclerView);
}
}
});
while (cursor.moveToNext()){
if(cursor.getString(4).equals("1")) {
location_id.add(cursor.getString(0));
location_name.add(cursor.getString(1));
location_county.add(cursor.getString(2));
location_description.add(cursor.getString(3));
location_route.add(cursor.getString(4));
location_position.add(cursor.getString(8));
}
}
routeAdapter = new routeAdapter(this, this, location_id, location_name, location_county, location_description, location_route, location_position);
recyclerView.setAdapter(routeAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}
and this is the route adapter class
public class routeAdapter extends RecyclerView.Adapter<routeAdapter.MyViewHolder> {
//private final ClickListener listener;
private Context context;
MyDatabaseHelper myDB;
Activity activity;
private ArrayList location_id, location_name, location_county, location_description, location_position, location_route, location_image_url;
Button btnRemove;
String id, name, county, description;
routeAdapter(Activity activity, Context context, ArrayList location_id, ArrayList location_name, ArrayList location_county,
ArrayList location_description, ArrayList location_route, ArrayList location_position){
this.activity = activity;
this.context = context;
this.location_id = location_id;
this.location_name = location_name;
this.location_county = location_county;
this.location_description = location_description;
this.location_position = location_position;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.route_row, parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, final int position) {
holder.location_id_txt.setText(String.valueOf(location_id.get(position)));
holder.location_name_txt.setText(String.valueOf(location_name.get(position)));
holder.location_county_txt.setText(String.valueOf(location_county.get(position)));
holder.location_description_txt.setText(String.valueOf(location_description.get(position)));
holder.mainLayout2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context, RouteView.class);
intent.putExtra("id", String.valueOf(location_id.get(position)));
intent.putExtra("name", String.valueOf(location_name.get(position)));
intent.putExtra("county", String.valueOf(location_county.get(position)));
intent.putExtra("description",String.valueOf(location_description.get(position)));
activity.startActivityForResult(intent, 2);
}
});
}
#Override
public int getItemCount() { return location_id.size(); }
class MyViewHolder extends RecyclerView.ViewHolder {
TextView location_id_txt, location_name_txt, location_county_txt, location_description_txt, added_to_route_txt, location_image_url;
LinearLayout mainLayout2;
Button btnRemove;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
location_id_txt = itemView.findViewById(R.id.location_id_txt);
location_name_txt = itemView.findViewById(R.id.location_name_txt);
location_county_txt = itemView.findViewById(R.id.location_county_txt);
location_description_txt = itemView.findViewById(R.id.location_description_txt);
mainLayout2 = itemView.findViewById(R.id.mainLayout2);
}
}
}
This is the basic concept:
On clicking a button or whatever to sort the things in a specific order, you sort the ArrayList that contains the values reflected in the RecyclerView. Then you update/ recreate the RecyclerView to register the changes.
I want to pass the edited text value from one activity to another activity and then display in the recyclerView.This is the errors I have
May be I have to put the value under equation marks? But I don't know how to put edited text value in them.
I want to pass data from this Class
public class addEvent extends AppCompatActivity {
public void addEvent(View view){
EditText timeEditText = findViewById(R.id.timeEditText);
EditText descriptionEditText = findViewById(R.id.descriptionEditText);
Intent intent = new Intent(getApplicationContext(), events.class);
String timeInfo = timeEditText.getText().toString();
String descriptionInfo = descriptionEditText.getText().toString();
intent.putExtra("time", timeInfo );
intent.putExtra("description", descriptionInfo);
}
public void events(View view){
Intent intent1 = new Intent(getApplicationContext(), events.class);
startActivity(intent1);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_event);
}
}
This is the View Activity
public class events extends AppCompatActivity {
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private List<ListItem> listItems;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_events);
recyclerView = findViewById(R.id.recyclerViewID);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
Bundle bundle = getIntent().getExtras();
String time = bundle.getString("time");
String description = bundle.getString("description");
listItems = new ArrayList<>();
listItems = new ArrayList<>();
ListItem item = new ListItem(time, "d");
listItems.add(item);
adapter = new MyAdapter(this, listItems);
recyclerView.setAdapter(adapter);
}
}
This is the Adapter Class
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private Context context;
private List<ListItem> listitem;
public MyAdapter(Context context, List listitems){
this.context = context;
this.listitem = listitems;
}
#NonNull
#Override
public MyAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_row, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyAdapter.ViewHolder viewHolder, int i) {
ListItem item = listitem.get(i);
viewHolder.time.setText(item.getTime());
viewHolder.description.setText(item.getDescription());
}
#Override
public int getItemCount() {
return listitem.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView time;
public TextView description;
public ViewHolder(#NonNull View itemView) {
super(itemView);
time = itemView.findViewById(R.id.time);
description = itemView.findViewById(R.id.description);
}
}
}
This is the Model Class
public class ListItem {
private String time;
private String description;
public ListItem(String time, String description) {
this.time = time;
this.description = description;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
You have to call startActivity from the same scope you are defining the extras:
public void addEvent(View view){
EditText timeEditText = findViewById(R.id.timeEditText);
EditText descriptionEditText = findViewById(R.id.descriptionEditText);
Intent intent = new Intent(getApplicationContext(), events.class);
String timeInfo = timeEditText.getText().toString();
String descriptionInfo = descriptionEditText.getText().toString();
intent.putExtra("time", timeInfo );
intent.putExtra("description", descriptionInfo);
startActivity(intent);//add this
}
In your addEvent() method,
public void addEvent(View view){
//your code
Intent intent = new Intent(addEvent.this, events.class);
Bundle bundle = new Bundle();
bundle.putString("time", timeInfo);
bundle.putString("description",descriptionInfo);
intent.putExtras(bundle);
startActivity(intent);
}
then, in your events activity and in onCreate() method,
Bundle bundle = getIntent().getExtras();
String time = bundle.getString("time");
String description = bundle.getString("description");
ArrayList<ListItem> arrayList = new ArrayList<>();
ListItem listItem = new ListItem(time, description);
arrayList.add(listItem);
adapter = new MyAdapter(this, arrayList);
recyclerView.setAdapter(adapter);
this will do your work.
You want to use "getStringExtra", not "getExtras/bundle"
public class AnimateToolbar extends AppCompatActivity {
private CollapsingToolbarLayout collapsingToolbar;
private AppBarLayout appBarLayout;
private DessertAdapter dessertAdapter;
private List<Dessert> persons;
private RecyclerView rv;
private Menu collapsedMenu;
private boolean appBarExpanded = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_animate_toolbar);
final Toolbar toolbar = (Toolbar) findViewById(R.id.anim_toolbar);
setSupportActionBar(toolbar);
if (getSupportActionBar() != null)
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
appBarLayout = (AppBarLayout) findViewById(R.id.appbar);
collapsingToolbar = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
collapsingToolbar.setTitle(getString(R.string.android_desserts));
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.header);
Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {
#SuppressWarnings("ResourceType")
#Override
public void onGenerated(Palette palette) {
int vibrantColor = palette.getVibrantColor(R.color.primary_500);
collapsingToolbar.setContentScrimColor(vibrantColor);
collapsingToolbar.setStatusBarScrimColor(R.color.black_trans80);
}
});
private void initializeData(){
persons = new ArrayList<>();
//when the user clicks on this card view or recycle view a youtube would open either in the youtube app or a browser that is available on the user mobile.
persons.add(new Dessert("Engine", "5.9-litre V12 engine ", R.mipmap.enginelogo));
persons.add(new Dessert("Lavery Maiss", "25 years old", R.drawable.lavery));
persons.add(new Dessert("Lillie Watts", "35 years old", R.drawable.lillie));
}
//I want to open an intent with the first position of persons so that it opens up a youtube video.
private void initializeAdapter(){
DessertAdapter adapter = new DessertAdapter(persons);
rv.setAdapter(adapter);
}
//I tried different approaches but none of them have worked out for me so far please help
//this is the adapter on which the upper recyclerview is based on
public class DessertAdapter extends RecyclerView.Adapter<DessertAdapter.DessertVh> {
public static class DessertVh extends RecyclerView.ViewHolder{
CardView cv;
TextView personName;
TextView personAge;
ImageView personPhoto;
DessertVh(View itemView){
super(itemView);
cv = (CardView)itemView.findViewById(R.id.cv);
personName = (TextView)itemView.findViewById(R.id.person_name);
personAge = (TextView)itemView.findViewById(R.id.person_age);
personPhoto = (ImageView) itemView.findViewById(R.id.person_photo);
}
}
List<Dessert> persons;
DessertAdapter(List<Dessert> persons){this.persons = persons;}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView){
super.onAttachedToRecyclerView(recyclerView);
}
#Override
public DessertVh onCreateViewHolder(ViewGroup viewGroup, int i){
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_dessert, viewGroup,false);
DessertVh dvh = new DessertVh(v);
return dvh;
}
#Override
public void onBindViewHolder(DessertVh dessertVh, int i){
dessertVh.personName.setText(persons.get(i).name);
dessertVh.personAge.setText(persons.get(i).age);
dessertVh.personPhoto.setImageResource(persons.get(i).photoId);
}
#Override
public int getItemCount(){return persons.size();}
}
You can set click on every item like this. You need to pass hold some url of video in list items. and you will start youtube activity with that url.
List<Dessert> persons;
Context context
DessertAdapter(Context context, List<Dessert> persons)
{
this.persons = persons;
this.context = context;
}
...
#Override
public void onBindViewHolder(DessertVh dessertVh, int i){
...
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Uri url = Uri.parse("vnd.youtube://" + video_id); // get your url from list item or your code.
Intent intent = new Intent(Intent.ACTION_VIEW, url);
context.startActivity(intent);
}
});
}
Call your adapter like
DessertAdapter adapter = new DessertAdapter(AnimateToolbar.this, persons);
rv.setAdapter(adapter);
Try something like this:
(in your OnItemClicklistener for RecylcerView):
Intent intent = new Intent(Intent.ACTION_SEND); intent.putExtra(Intent.EXTRA_TEXT, persons.get(position); intent.setPackage("com.google.android.apps.youtube.app"); startActivity(intent);
I hope this helps! :D
I initially followed the accepted answer in this previously posted question about how to save and restore the layout manager for a RecyclerView.
I have my RecyclerView in Activity B. [Note: Activity A will launch Activity B, transferring data via an intent.]
When a user clicks a viewholder in Activity B, Activity C is launched. Once Activity C is closed and destroyed, Activity B is visible, and I can see all of my data restored in the RecyclerView.
The Problem:
However, if I navigate away from my app (ie pressing the Home Key), it is pushed to the background. When my app is reinstated, onCreate() is called again. The LayoutManager's state is being saved, however none of my data is showing in the RecyclerView.
I can tell my LayoutManager state was saved after some debugging. It shows up as this when onCreate() is called again after reinstating the app from the background:
Saved Instance State = Bundle[{ActivityB - Linear Layout State=android.support.v7.widget.LinearLayoutManager$SavedState#6358f8f, android:viewHierarchyState=Bundle[mParcelledData.dataSize=1296]}]
I am not sure how to fix this after hours of trying.
My Code:
public class ActivityB extends AppCompatActivity {
private RecyclerView recyclerView;
private LinearLayoutManager linearLayoutManager;
private Parcelable linearLayoutState;
private RecyclerAdapter adapter;
private Button more;
private String id;
private List<VideoItem> list;
private List<VideoItem> newList;
private final String LINEARLAYOUT_STATE_KEY = "Activity B - Linear Layout State";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_blayout);
// Retrieving data from Activity A
Intent intent = getIntent();
Bundle bundle = intent.getBundleExtra("bundle");
someClass.innerClass class = bundle.getParcelable("data");
id = class.getID();
list = class.getList();
newList = new ArrayList<>();
// Instantiating Recycler View
recyclerView = (RecyclerView)findViewById(R.id.activityb_recyclerview);
recyclerView.setNestedScrollingEnabled(false);
linearLayoutManager = new LinearLayoutManager(context);
recyclerView.setLayoutManager(linearLayoutManager);
adapter = new RecyclerAdapter();
recyclerView.setAdapter(adapter);
moreButton = (Button)findViewById(R.id.activityb_more);
moreButton.setOnClickListener(new fetchMoreClickListener());
}
#Override
public void onResume(){
if (linearLayoutState != null) {
linearLayoutManager.onRestoreInstanceState(linearLayoutState);
} else {
// If no layout state is found, I need to populate my
// adapter.
// Here I am simply cloning my list again, to keep the original
// list intact. generateSubset() removes items from the cloned list
// to create a smaller subset that is added to the adapter.
for (ListItem item : list){
newList.add(new ListItemi(item));
}
adapter.addItems(generateSubset(0));
}
super.onResume();
}
#Override
protected void onSaveInstanceState(Bundle outState) {
linearLayoutState = linearLayoutManager.onSaveInstanceState();
outState.putParcelable(LINEARLAYOUT_STATE_KEY, linearLayoutState);
super.onSaveInstanceState(outState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
linearLayoutState = savedInstanceState.getParcelable(LINEARLAYOUT_STATE_KEY);
}
The other Activity LifeCycle Methods have not been overridden. I am not getting any error messages. Just my data stored in my viewholders is no longer showing in the RecyclerView.
Edit 1:
Here is my RecyclerAdapter code:
public class RecyclerAdapter extends RecyclerView.Adapter{
private static Date now;
private List list;
public static class ItemHolder extends RecyclerView.ViewHolder
implements View.OnClickListener {
private Context context;
private String key;
private Bundle itemBundle;
private SimpleDraweeView photo;
private TextView title;
public ItemHolder(Context context, View view){
super(view);
this.context = context;
this.key = null;
this.itemBundle = null;
photo = (SimpleDraweeView)view.findViewById(R.id.itemholder_photo);
title = (TextView)view.findViewById(R.id.itemholder_title);
view.setOnClickListener(this);
}
public void bindData(Item item){
if (key == null){ key = item.getID(); }
if (itemBundle == null){
itemBundle = new Bundle();
itemBundle.setClassLoader(Item.class.getClassLoader());
itemBundle.putParcelable("data", item);
}
photo.setImageURI(Uri.parse(item.getPhotoURL()));
}
#Override
public void onClick(View view) {
Intent intent = new Intent(context, ActivityB.class);
intent.putExtra("bundle", itemBundle);
context.startActivity(intent);
}
}
public RecyclerAdapter(){
this.list = new ArrayList<>();
this.now = new Date();
}
public RecyclerAdapter(ArrayList<VideoItem> list){
this.list = list;
this.now = new Date();
this.notifyItemRangeInserted(0, list.size());
}
#Override
public RecyclerAdapter.ItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
View recyclerItem = LayoutInflater.from(context)
.inflate(R.layout.itemholder_item, parent, false);
return new ItemHolder(context, recyclerItem);
}
#Override
public void onBindViewHolder(RecyclerAdapter.ItemHolder holder, int position) {
Item item = list.get(position);
holder.bindData(item);
}
private static Date getNow(){ return now; }
private static void updateNow(){ now = new Date(); }
#Override
public int getItemCount() {
return list.size();
}
public void addItem(Item item){
list.add(item);
this.notifyItemInserted(list.size() - 1);
}
public void addItems(ArrayList<Item> items){
int oldSize = list.size();
list.addAll(items);
this.notifyItemRangeInserted(oldSize, items.size());
}
}
Try changing your onResume() method to look something like the following:
#Override
public void onResume(){
super.onResume();
if (linearLayoutState != null) {
linearLayoutManager.onRestoreInstanceState(linearLayoutState);
}
// Here comes the code to populate your data.
// I'm not sure how you do this, so I just copy/paste your code
for (ListItem item : list){
newList.add(new ListItemi(item));
}
// Now instatiate and add the adapter to the RecyclerView
adapter = new RecyclerAdapter(newList);
recyclerView.setAdapter(adapter);
}
}
I have a question about passing clicked cardview data to activity, and here the full story :
I have an Activity called "Details", which contains 2 TextViews in it's layout, Title & Description .
I have setup a fragment ( tab_1 ) which contain the recyclerview codes and the the items data, each item of those contain : title & description .
What i want :
When the user click the item, it will open the Details Activity, and change Details layout title, with clicked item title, and the same for description .
I've manged to create the other activity as an example, and made intent to start it, plus adding "addOnTouchlistener" thanks to Stackoverflow, i've found the way to make it .
So, how to make this alive? I've tried many ways of the available answers on Stackoverflow, but all of them not working, or not related to my request .
Here are my files :
itemsdata.java :
public class itemsdata {
int CatPic;
String title;
String Descr;
int Exapnd;
int expand_no;
tab_1.java ( fragment )
public class tab_1 extends Fragment implements SearchView.OnQueryTextListener {
private RecyclerView mRecyclerView;
public RecyclingViewAdapter adapter;
private Activity context;
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View layout = inflater.inflate(R.layout.tab_1, container, false);
mRecyclerView = (RecyclerView)layout.findViewById(R.id.recycler_view);
mRecyclerView.addOnItemTouchListener(new RecyclerItemClickListener
(getContext(), new RecyclerItemClickListener.OnItemClickListener() {
#Override
public void onItemClick(View view, int position) {
Intent i = new Intent(view.getContext(), DetailsActivity.class);
view.getContext().startActivity(i);
}
}));
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
adapter = new RecyclingViewAdapter(getActivity(),Listed());
mRecyclerView.setAdapter(adapter);
return layout;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.main, menu);
final MenuItem item = menu.findItem(R.id.action_search);
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
searchView.setOnQueryTextListener(this);
}
#Override
public boolean onQueryTextChange(String query) {
final List<itemsdata> filteredModelList = filter(Listed(), query);
adapter.animateTo(filteredModelList);
mRecyclerView.scrollToPosition(0);
return true;
}
#Override
public boolean onQueryTextSubmit(String query) {
return true;
}
private List<itemsdata> filter(List<itemsdata> models, String query) {
query = query.toLowerCase();
final List<itemsdata> filteredModelList = new ArrayList<>();
for (itemsdata model : models) {
final String text = model.title.toLowerCase();
if (text.contains(query)) {
filteredModelList.add(model);
}
}
return filteredModelList;
}
public List<itemsdata> Listed()
{
//Titles Strings
String sys_title1 = getString(R.string.system_item_title_1);
String sys_title2 = getString(R.string.system_item_title_2);
String sys_title3 = getString(R.string.system_item_title_3);
//Description Strings
String sys_descr1 = getString(R.string.system_item_desc_1);
String sys_descr2 = getString(R.string.system_item_desc_2);
String sys_descr3 = getString(R.string.system_item_desc_3);
//Adding New Cards
List<itemsdata> data = new ArrayList<>();
//Categories Icons New Items ** Make It The Same
int[] icons = {
R.drawable.facebook_icon ,
R.drawable.twitter_icon ,
R.drawable.twitter_icon
};
//Expand Button New Items
int[] expandbutton = {
R.drawable.expanded ,
R.drawable.expanded ,
R.drawable.expanded
};
//UnExpand Button New Items
int[] unexpandbutton = {
R.drawable.ca_expand ,
R.drawable.ca_expand ,
R.drawable.ca_expand
};
//Titles New Items
String[] titles = {
sys_title1 ,
sys_title2 ,
sys_title3
};
//Description New Items
String[] Description = {
sys_descr1 ,
sys_descr2 ,
sys_descr3
};
for(int i = 0;i<titles.length && i < icons.length && i < Description.length && i < unexpandbutton.length && i < expandbutton.length ; i++)
{
itemsdata current = new itemsdata();
current.CatPic = icons[i];
current.title = titles[i];
current.Descr = Description[i];
current.expand_no = unexpandbutton[i];
current.Exapnd = expandbutton[i];
data.add(current);
}
return data;
}
}
Details Activity :
public class DetailsActivity extends AppCompatActivity{
TextView title;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.details);
title = (TextView)findViewById(R.id.details_title);
}
EDIT : I've made it, i have added a button which open the fragment, and passed the data, in the Adapter, but i want it via tab_1.java, not the Adapter, i mean i want to click on the item to open the fragment, not on a button, here a snap from my Adapter code ( i've added it in OnBindViewHolder )
I've setup a OnClick and implemented the Vew.setOnClick ..etc, but when i click the item, nothing happen.
#Override
public void onBindViewHolder(final MyRecycleViewHolder holder, int position) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(v.getContext(),DetailsActivity.class);
v.getContext().startActivity(i);
}
});
//Referencing Data
final itemsdata currentobject = mdata.get(position);
//Referencing Items
holder.ProbTitle.setText(currentobject.title);
holder.ProbDescr.setText(currentobject.Descr);
holder.CategoryPic.setImageResource(currentobject.CatPic);
holder.ExpandButton.setImageResource(currentobject.Exapnd);
holder.ExpandNoButton.setImageResource(currentobject.expand_no);
//What Happen When You Click Expand Button .
holder.ExpandButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(v.getContext(), DetailsActivity.class);
i.putExtra("TitleKey",holder.ProbTitle.getText().toString());
v.getContext().startActivity(i);
}
}
);
public static class MyRecycleViewHolder extends RecyclerView.ViewHolder
{
SwipeLayout swipeLayout;
//Defining Items .
TextView ProbTitle;
ImageButton ExpandButton;
TextView ProbDescr;
ImageButton ExpandNoButton;
ImageView CategoryPic;
/*
TextView Card_Star;
TextView Card_UnStar;
*/
TextView Card_Share;
//Referencing Resources
public MyRecycleViewHolder(final View itemView) {
super(itemView);
ProbTitle = (TextView) itemView.findViewById(R.id.prob_title);
CategoryPic = (ImageView) itemView.findViewById(R.id.cat_pic);
ProbDescr = (TextView) itemView.findViewById(R.id.prob_descr);
ExpandButton = (ImageButton) itemView.findViewById(R.id.expand_button);
ExpandNoButton = (ImageButton) itemView.findViewById(R.id.expand_no_button);
/*
Card_Star = (TextView) itemView.findViewById(R.id.card_star);
Card_UnStar = (TextView) itemView.findViewById(R.id.card_unstar);
*/
Card_Share = (TextView) itemView.findViewById(R.id.card_share);
swipeLayout = (SwipeLayout) itemView.findViewById(R.id.swipe);
}
create an Interface inside your adapter containing methods. And while implementing your Adapter, those methods will be implemented in your activity and you can perform whatever action you want.
public class Adapter extends RecyclerView.Adapter<MyRecycleViewHolder> {
public interface Callbacks {
public void onButtonClicked(String titleKey);
}
private Callbacks mCallbacks;
public Adapter() {
}
#Override
public MyRecycleViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.layout_details, null);
return new MyRecycleViewHolder(v);
}
#Override
public void onBindViewHolder(final MyRecycleViewHolder holder, final int i) {
holder.ExpandButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mCallbacks != null) {
mCallbacks.onButtonClicked(holder.ProbTitle.getText().toString());
}
}
});
}
#Override
public int getItemCount() {
return;
}
public void setCallbacks(Callbacks callbacks) {
this.mCallbacks = callbacks;
}
}
you may try do this on your onItemClick()
Intent i = new Intent(view.getContext(), DetailsActivity.class);
i.putExtra("title", yourTitle);
i.putExtra("description", yourDescription);
view.getContext().startActivity(i);
and when oncreate in your DetailActivity,do this
String title = getIntent().getStringExtra("title");
String description = getIntent().getStringExtra("description");
so you can pass title and description to DetailActivity
IMO, you implement setOnClickListener inside Adapter of RecyclerView. You can refer to my following sample code, then apply its logic to your code. Hope it helps!
public class MyRVAdapter extends RecyclerView.Adapter<MyRVAdapter.ViewHolder> {
Context mContext;
List<String> mStringList;
public MyRVAdapter(Context mContext, List<String> mStringList) {
this.mContext = mContext;
this.mStringList = mStringList;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview, parent, false);
v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
TextView textView1 = (TextView) v.findViewById(R.id.textView1);
TextView textView2 = (TextView) v.findViewById(R.id.textView2);
Bundle bundle = new Bundle();
bundle.putString("key1", textView1.getText().toString());
bundle.putString("key2", textView2.getText().toString());
passToAnotherActivity(bundle);
}
});
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
// do something...
}
#Override
public int getItemCount() {
if (mStringList != null) {
return mStringList.size();
}
return 0;
}
private void passToAnotherActivity(Bundle bundle) {
if (mContext == null)
return;
if (mContext instanceof MainActivity) {
MainActivity activity = (MainActivity) mContext;
activity.passToAnotherActivity(bundle); // this method must be implemented inside `MainActivity`
}
}
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public ViewHolder(View itemView) {
super(itemView);
// do something...
}
#Override
public void onClick(View v) {
}
}
}
First of all make your "itemsdata" object to implement Parcelable. You can check it here . In your onItemClick method you pass the object to your Details activity using intent.putExtra("key",listOfDataItems.get(position));
In your DetailsActivity you can get your custom object with getParcelable("key")
All above methods worked, but kinda long, so this one worked for me :
Cardview cardview;
cardView = (CardView)itemView.findViewById(R.id.cv);
cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent (view.getContext(), DetailsActivity.class);
i.putExtra("TitleKey",ProbTitle.getText().toString());
i.putExtra("DescrKey",ProbDescr.getText().toString());
view.getContext().startActivity(i);
}
});
And in Details.java :
TextView title;
TextView Descr;
title = (TextView)findViewById(R.id.details_title);
Descr = (TextView)findViewById(R.id.details_descr);
String titleresult = result.getExtras().getString("TitleKey");
String Descrresult = result.getExtras().getString("DescrKey");
title.setText(titleresult);
Descr.setText(Descrresult);