I'm trying to list data from serializable object but it doesn't work show nothing.
I am listing information from a recyclerview with serialized object. When passing to another activity, the recyclerview does not show any data.
Sorry about my english.
MainActivity
private void onOrderProduct() {
bOrder.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Cart cart = new Cart();
cart.setComida(tvTitle.getText().toString());
cart.setPreco(tvTotal.getText().toString());
cart.setQuantidade(tvQtd.getText().toString());
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
intent.putExtra("cart", cart);
startActivity(intent);
}
});
}
SecondActivity
public class SecondActivity extends AppCompatActivity {
RecyclerView rvCart;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.secondactivity);
rvCart = (RecyclerView) findViewById(R.id.tela5recycler_view);
rvCart.setHasFixedSize(true);
LinearLayoutManager manager = new LinearLayoutManager(this);
rvCart.setLayoutManager(manager);
if (getIntent().getSerializableExtra("cart") != null) {
Intent intent = getIntent();
Cart cart = (Cart) intent.getSerializableExtra("cart");
ArrayList<Cart> eList = new ArrayList<>() cart;
Adapter adapter =new Adapter(getApplicationContext(), eList );
rvCart.setAdapter(adapter);
}
}
}
Adapter
public class Adapter extends RecyclerView.Adapter<Adapter.ItemViewHolder> {
private Context context;
private ArrayList<Cart> itemList;
public Adapter(Context context, ArrayList<Cart> itemList){
this.context = context;
this.itemList = itemList;
}
#Override
public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.from(parent.getContext())
.inflate(R.layout.adapter_card, parent, false);
ItemViewHolder itemViewHolder = new ItemViewHolder(view);
return itemViewHolder;
}
#Override
public void onBindViewHolder(ItemViewHolder holder, int position) {
Cart item = itemList.get(position);
holder.tvQtdcard.setText(item.getQuantidade());
holder.tvComidacard.setText(item.getComida());
holder.tvPrecocard.setText(item.getPreco());
}
#Override
public int getItemCount() {
if(itemList != null){
return itemList.size();
}
return 0;
}
public static class ItemViewHolder extends RecyclerView.ViewHolder{
public CardView cvItem;
public TextView tvQtdcard, tvComidacard, tvPrecocard;
public ItemViewHolder(View itemView) {
super(itemView);
cvItem = (CardView)itemView.findViewById(R.id.tela1_1_1_1_1card);
tvQtdcard = (TextView)itemView.findViewById(R.id.tela5qtdcard);
tvComidacard = (TextView)itemView.findViewById(R.id.tela5comidacard);
tvPrecocard = (TextView)itemView.findViewById(R.id.tela5precocard);
}
}
}
Cart.class Serializable
import java.io.Serializable;
public class Cart implements Serializable{
private static final long serialVersionUID = 42L;
private String comida;
private String quantidade;
private String preco;
public String getComida() {
return comida;
}
public void setComida(String comida) {
this.comida = comida;
}
public String getQuantidade() {
return quantidade;
}
public void setQuantidade(String quantidade) {
this.quantidade = quantidade;
}
public String getPreco() {
return preco;
}
public void setPreco(String preco) {
this.preco = preco;
}
public String toString(){
return comida;
}
}
You are missing adapter.notifyDataSetChanged() after and you are passing empty arraylist eList
ArrayList<Cart> eList = new ArrayList<>();
eList.add(cart);
Adapter adapter =new Adapter(getApplicationContext(), eList );
rvCart.setAdapter(adapter);
To pass the serialized object
Solution 1 (Hackytack solution)
public class CardListHolder implements Serializable{
private ListcardList=new ArrayList<>();
public List<Card>getCardList(){
return cardList;
}
public void setCardList(List<Card> cardList){
this.cardList=cardList;
}
}
Use this holder object to pass the list of card
Solution 2
Implement Parcelable for Card object, it can pass list of card but it is little bit complex to understand. Try www.parcelabler.com to auto generate the Parceable class for Card.
Related
I am trying to insert info about movie but I am getting this error:
java.lang.NullPointerException: Attempt to invoke virtual method 'void kawi15.myapplication.database.DatabaseViewModel.addWatchlistMovie(info.movito.themoviedbapi.model.MovieDb)' on a null object reference
I am sure that Movie is not null because I have Toast which showing me info about this movie.
I find that I need initializate DatabaseViewModel in my OnCreate():
databaseViewModel = new ViewModelProvider(this).get(DatabaseViewModel.class);
but I tried this in OnCreate and OnCreateView and in both its error with 'this':
new ViewModelProvider(this)
I try to put there getContext() or some other stuff but nothing worked here.
This is my Entity class:
#Entity
public class Watchlist {
#PrimaryKey
#ColumnInfo(name = "id")
private int movieId;
#ColumnInfo(name = "movie_title")
private String movieTitle;
#ColumnInfo(name = "poster_path")
private String posterPath;
#ColumnInfo(name = "overview")
private String overview;
#ColumnInfo(name = "release_date")
private String releaseDate;
and getters and setters for all
My Dao class:
#Dao
public interface WatchlistDao {
#Query("SELECT * FROM watchlist ORDER BY movie_title ASC")
List<Watchlist> getAll();
#Insert
void addMovie(Watchlist watchlistMovie);
}
ViewModel class:
public class DatabaseViewModel extends AndroidViewModel {
private AppDatabase db;
public DatabaseViewModel(#NonNull Application application) {
super(application);
db = AppDatabase.getDatabase(application);
}
public void addWatchlistMovie(MovieDb movieDb){
Watchlist addedMovie = new Watchlist();
addedMovie.setMovieId(movieDb.getId());
addedMovie.setMovieTitle(movieDb.getOriginalTitle());
addedMovie.setOverview(movieDb.getOverview());
addedMovie.setPosterPath(movieDb.getPosterPath());
addedMovie.setReleaseDate(movieDb.getReleaseDate());
db.watchlistDao().addMovie(addedMovie);
}
My Fragment class where I am clicking on Movie from list that I want to insert to database:
public class FragmentOne extends Fragment /*implements CustomAdapter.ListItemClickListener*/{
private static RecyclerView.Adapter adapter;
private RecyclerView.LayoutManager layoutManager;
private DatabaseViewModel databaseViewModel;
private static RecyclerView recyclerView;
private List<MovieDb> data;
//private CustomAdapter.ListItemClickListener mOnClickListener;
public static FragmentOne newInstance() {
FragmentOne fragment = new FragmentOne();
return fragment;
}
/*#Override
public void onListItemClick(int position) {
Toast.makeText(getContext(), data.get(position).getOriginalTitle(), LENGTH_SHORT).show();
}*/
public class MovieTask extends AsyncTask<Void, Void, List<MovieDb>> {
#Override
protected List<MovieDb> doInBackground(Void... voids) {
MovieResultsPage movies = new TmdbApi("f753872c7aa5c000e0f46a4ea6fc49b2").getMovies().getUpcoming("en-US", 1, "US");
List<MovieDb> listMovies = movies.getResults();
return listMovies;
}
#Override
protected void onPostExecute(List<MovieDb> movieDb) {
data = movieDb;
adapter = new CustomAdapter(data);
((CustomAdapter) adapter).setOnMovieDbClicked(movieDb2 -> {
Toast.makeText(getActivity(), movieDb2.getReleaseDate(), LENGTH_SHORT).show();
databaseViewModel.addWatchlistMovie(movieDb2);
});
recyclerView.setAdapter(adapter);
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View returnView = inflater.inflate(R.layout.fragment_one, container, false);
recyclerView = (RecyclerView) returnView.findViewById(R.id.my_recycler_view);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(getContext()); // ???
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
MovieTask mt = new MovieTask();
mt.execute();
return returnView;
}
}
and my adapter class, maybe not neccessary:
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.MyViewHolder>{
private List<MovieDb> dataSet;
private OnMovieDbClicked onMovieDbClicked;
public void setOnMovieDbClicked(OnMovieDbClicked onMovieDbClicked) {
this.onMovieDbClicked = onMovieDbClicked;
}
//final private ListItemClickListener mOnClickListener;
public class MyViewHolder extends RecyclerView.ViewHolder /*implements View.OnClickListener*/{
TextView textViewName;
TextView textViewVersion;
ImageView imageViewIcon;
//private ListItemClickListener mOnClickListener;
public MyViewHolder(View itemView) {
super(itemView);
this.textViewName = (TextView) itemView.findViewById(R.id.text1);
this.textViewVersion = (TextView) itemView.findViewById(R.id.text2);
this.imageViewIcon = (ImageView) itemView.findViewById(R.id.imageView);
itemView.setOnClickListener(view -> {
int pos = getAdapterPosition();
if (onMovieDbClicked != null && pos != RecyclerView.NO_POSITION) {
MovieDb movieDb = dataSet.get(pos);
onMovieDbClicked.movieDbClicked(movieDb);
}
});
//itemView.setOnClickListener(this);
//itemView.setOnClickListener(CustomAdapter.myOnClickListener);
}
/*#Override
public void onClick(View v) {
int position = getAdapterPosition();
mOnClickListener.onListItemClick(position);
}*/
}
public CustomAdapter(List<MovieDb> data /*ListItemClickListener mOnClickListener*/) {
this.dataSet = data;
//this.mOnClickListener = mOnClickListener;
}
public interface OnMovieDbClicked {
void movieDbClicked(MovieDb movieDb);
}
/*public interface ListItemClickListener{
void onListItemClick(int position);
}*/
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.cards_layout, parent, false);
//view.setOnClickListener(FragmentOne.myOnClickListener);
MyViewHolder myViewHolder = new MyViewHolder(view);
return myViewHolder;
}
#Override
public void onBindViewHolder(final MyViewHolder holder, final int listPosition) {
TextView textViewName = holder.textViewName;
TextView textViewVersion = holder.textViewVersion;
ImageView imageView = holder.imageViewIcon;
Glide.with(imageView).load("https://image.tmdb.org/t/p/w500" + dataSet.get(listPosition).getPosterPath()).into(imageView);
textViewName.setText(dataSet.get(listPosition).getOriginalTitle());
textViewVersion.setText(dataSet.get(listPosition).getReleaseDate());
}
#Override
public int getItemCount() {
if(dataSet == null){
return 0;
}
return dataSet.size();
}
}
You have not initialized your databaseViewModel anywhere so the NPE is expected. Make sure to fill the field before accessing it in MovieTask
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;
}
}
This is my adapter for recycle view
CategoryAdapter Class
public class CategoryRAdapter extends RecyclerView.Adapter<CategoryRAdapter.MyViewHolder> {
private Context mcontext;
private List<Food> mData;
RequestOptions option;
public CategoryRAdapter(Context mcontext, List<Food> mData) {
this.mcontext = mcontext;
this.mData = mData;
option = new RequestOptions().centerCrop().placeholder(R.drawable.loading_shape).error(R.drawable.loading_shape);
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.food_row, parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
Food current = mData.get(position);
holder.tv_Name.setText(current.getName());
holder.tv_Rating.setText(current.getRating());
holder.tv_Descip.setText(current.getDescrip());
holder.tv_Category.setText(current.getCateg());
Glide.with(mcontext).load(mData.get(position).getImages()).apply(option).into(holder.img_Thumbnail);
}
#Override
public int getItemCount() {
return mData.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView tv_Name;
TextView tv_Rating;
TextView tv_Descip;
TextView tv_Category;
ImageView img_Thumbnail;
public MyViewHolder(View itemView) {
super(itemView);
tv_Name = itemView.findViewById(R.id.food_name);
tv_Rating = itemView.findViewById(R.id.rating);
tv_Descip = itemView.findViewById(R.id.desc);
tv_Category = itemView.findViewById(R.id.category);
img_Thumbnail = itemView.findViewById(R.id.thumbnail);
}
}
}
This is my model
Food Class
public class Food {
String Name;
String Images;
String Descrip;
String Rating;
String Categ;
public Food() {
}
public Food(String name, String images, String descrip, String rating, String categ) {
this.Name = name;
this.Images = images;
this.Descrip = descrip;
this.Rating = rating;
this.Categ = categ;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public String getImages() {
return Images;
}
public void setImages(String images) {
Images = images;
}
public String getDescrip() {
return Descrip;
}
public void setDescrip(String descrip) {
Descrip = descrip;
}
public String getRating() {
return Rating;
}
public void setRating(String rating) {
Rating = rating;
}
public String getCateg() {
return Categ;
}
public void setCateg(String categ) {
Categ = categ;
}
}
My mian activity
CategoryActivity Class
public class CategoriaActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private List<Food> dbObjects;
private RecyclerView.Adapter adapter;
private AlertDialog.Builder dialogBuilder;
private AlertDialog dialog;
TextView l_nombre,l_precio;
Button l_finalizar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_categoria);
recyclerView = findViewById(R.id.recycle_id);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
dbObjects = new ArrayList<>();
ParseQuery<ParseObject> query = ParseQuery.getQuery("Category");
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> objList, ParseException e) {
if (e == null) {
for (ParseObject obj : objList) {
Food food = new Food();
food.setName(obj.getString("Name"));
food.setDescrip(obj.getString("Descrip"));
food.setRating(obj.getString("Rating"));
food.setCateg(obj.getString("Categ"));
food.setImages(obj.getString("Images"));
dbObjects.add(food);
}
} else {
FancyToast.makeText(CategoriaActivity.this, "Error: " + e.getMessage(), FancyToast.LENGTH_SHORT, FancyToast.ERROR, true).show();
}
}
});
adapter = new CategoryRAdapter(this, dbObjects);
recyclerView.setAdapter(adapter);
FloatingActionButton fab = findViewById(R.id.shoppingFlot);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
carritopop();
}
});
}
private void carritopop() {
dialogBuilder = new AlertDialog.Builder(this);
View view = getLayoutInflater().inflate(R.layout.pop_cart,null);
l_finalizar = view.findViewById(R.id.l_finalizar);
l_finalizar.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
pago();
}
});
dialogBuilder.setView(view);
dialog = dialogBuilder.create();
dialog.show();
}
private void pago() {
Intent intent = new Intent(CategoriaActivity.this, PagoActivity.class);
startActivity(intent);
}
}
I dont know whats wrong with the code, the recycle view aint working, it aint showing any items, i would really appreciate if someone could help me out and notice something wrong in my code
Call adapter.notifyDataSetChanged() in your query done callback, this will notify the adapter that the list has changed. This is happening because when you set the adapter, the list was empty as the query was running in background. Once it completes, you have to tell the adapter that new data has been added to list:
if (e == null) {
for (ParseObject obj : objList) {
...
}
adapter.notifyDataSetChanged();
}
Also, create your adapter before you send the query otherwise it may result in NullPointerException in case data is loaded before the next statement executes (highly unlikely but never hurts to be safe).
dbObjects = new ArrayList<>();
adapter = new CategoryRAdapter(this, dbObjects);
ParseQuery<ParseObject> query = ParseQuery.getQuery("Category");
I recommend you to use RxJava2 to user asynchronous methods, it's awesome... And about the problem, maybe your data is not ready when you're already creating the adapter with the ArrayList.
Try to move the recyclerView.setAdapter() to inside the FindCallback after create the Food Objects.
I was just playing around with some code, learning new things, when I ran into this problem... I'm trying to pass a variable from my RecylcerViewAdapter to a method in MainActivity, but I just can't seem to accomplish it.
I tried a lot of different thing with interfaces and casting, but nothing did the trick. Since I'm fairly new to all of this, maybe I'm making a trivial mistake somewhere?
My Interface:
public interface AdapterCallback {
void onMethodCallback(int id);
}
This is my adapter class:
public class PostAdapter extends RecyclerView.Adapter<PostAdapter.ViewHolder> {
private List<Post> postList;
private Context context;
private AdapterCallback listener;
public PostAdapter() {
}
public PostAdapter(List<Post> postList, Context context) {
this.postList = postList;
this.context = context;
}
public void setListener(AdapterCallback listener) {
this.listener = listener;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.recycler_layout, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder viewHolder, final int position) {
viewHolder.tvTitle.setText(postList.get(position).getTitle());
viewHolder.tvBody.setText(new StringBuilder(postList.get(position).getBody().substring(0, 20)).append("..."));
viewHolder.tvId.setText(String.valueOf(postList.get(position).getUserId()));
viewHolder.parentLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int id = postList.get(position).getId();
if (listener != null) {
listener.onMethodCallback(id);
}
}
});
}
#Override
public int getItemCount() {
return postList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView tvTitle;
TextView tvBody;
TextView tvId;
LinearLayout parentLayout;
public ViewHolder(View itemView) {
super(itemView);
tvTitle = itemView.findViewById(R.id.tvTitle);
tvBody = itemView.findViewById(R.id.tvBody);
tvId = itemView.findViewById(R.id.tvId);
parentLayout = itemView.findViewById(R.id.parentLayout);
}
}
}
And my MainActivity:
public class MainActivity extends AppCompatActivity {
public static final String TAG = "MainActivityLog";
private CompositeDisposable disposable = new CompositeDisposable();
#BindView(R.id.rvPosts)
RecyclerView rvPosts;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
rvPosts.setHasFixedSize(true);
rvPosts.setLayoutManager(new LinearLayoutManager(this));
populateList();
logItems();
}
private void populateList() {
MainViewModel viewModel = ViewModelProviders.of(MainActivity.this).get(MainViewModel.class);
viewModel.makeQuery().observe(MainActivity.this, new Observer<List<Post>>() {
#Override
public void onChanged(#Nullable List<Post> posts) {
PostAdapter adapter = new PostAdapter(posts, getApplicationContext());
rvPosts.setAdapter(adapter);
}
});
}
public void logItems() {
PostAdapter adapter = new PostAdapter();
adapter.setListener(new AdapterCallback() {
#Override
public void onMethodCallback(int id) {
MainViewModel viewModel = ViewModelProviders.of(MainActivity.this).get(MainViewModel.class);
viewModel.makeSingleQuery(id).observe(MainActivity.this, new Observer<Post>() {
#Override
public void onChanged(#Nullable final Post post) {
Log.d(TAG, "onChanged: data response");
Log.d(TAG, "onChanged: " + post);
}
});
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
disposable.clear();
}
}
The populateList() method works just fine, but the logItems() method is the problem.
So when i click on a view in RecyclerView I expect the log to output the title, description and ID of the post that was clicked. nut nothing happens...
So, any help would be appreciated.
Make adapter global variable i.e. a field. Use the same object to set every properties.
private PostAdapter adapter;
Replace your logItems method with this:
public void logItems() {
adapter.setListener(new AdapterCallback() {
#Override
public void onMethodCallback(int id) {
MainViewModel viewModel = ViewModelProviders.of(MainActivity.this).get(MainViewModel.class);
viewModel.makeSingleQuery(id).observe(MainActivity.this, new Observer<Post>() {
#Override
public void onChanged(#Nullable final Post post) {
Log.d(TAG, "onChanged: data response");
Log.d(TAG, "onChanged: " + post);
}
});
}
});
}
And populateList with this:
private void populateList() {
MainViewModel viewModel = ViewModelProviders.of(MainActivity.this).get(MainViewModel.class);
viewModel.makeQuery().observe(MainActivity.this, new Observer<List<Post>>() {
#Override
public void onChanged(#Nullable List<Post> posts) {
adapter = new PostAdapter(posts, getApplicationContext());
rvPosts.setAdapter(adapter);
logItems();
}
});
}
And don't call logItems() from onCreate
This is how I implement with my ListAdapters:
public class FeedbackListAdapter extends RecyclerView.Adapter<FeedbackListAdapter.ViewHolder> {
private final ArrayList<Feedback> feedbacks;
private View.OnClickListener onItemClickListener;
private View.OnLongClickListener onItemLongClickListener;
private final Context context;
public FeedbackListAdapter(ArrayList<Feedback> feedbacks, Context context) {
this.feedbacks = feedbacks;
this.context = context;
}
public void setItemClickListener(View.OnClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
public void setOnItemLongClickListener(View.OnLongClickListener onItemLongClickListener){
this.onItemLongClickListener = onItemLongClickListener;
}
public class ViewHolder extends RecyclerView.ViewHolder{
final TextView feedback, created, updated;
final LinearLayout mainLayout;
ViewHolder(View iv) {
super(iv);
/*
* Associate layout elements to Java declarations
* */
mainLayout = iv.findViewById(R.id.main_layout);
feedback = iv.findViewById(R.id.feedback);
created = iv.findViewById(R.id.created_string);
updated = iv.findViewById(R.id.updated_string);
}
}
#Override
public int getItemCount() {
return feedbacks.size();
}
#Override
#NonNull
public FeedbackListAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fragment_feedback_table_row, parent, false);
return new FeedbackListAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(final #NonNull FeedbackListAdapter.ViewHolder holder, final int position) {
/*
* Bind data to layout
* */
try{
Feedback feedback = feedbacks.get(position);
holder.feedback.setText(feedback.getContent());
holder.created.setText(feedback.getCreated());
holder.updated.setText(feedback.getUpdated());
holder.mainLayout.setOnClickListener(this.onItemClickListener);
holder.mainLayout.setOnLongClickListener(this.onItemLongClickListener);
holder.mainLayout.setTag(feedback.getDbID());
TypedValue outValue = new TypedValue();
context.getTheme().resolveAttribute(android.R.attr.selectableItemBackground, outValue, true);
holder.mainLayout.setBackgroundResource(outValue.resourceId);
}catch(IndexOutOfBoundsException e){
e.printStackTrace();
}
}
}
In onPopulateList you create an adaptor:
PostAdapter adapter = new PostAdapter(posts, getApplicationContext());
rvPosts.setAdapter(adapter);
However in public void logItems() { you used a different adapter
PostAdapter adapter = new PostAdapter();
adapter.setListener(new AdapterCallback() {
#Override
public void onMethodCallback(int id) {
...
}
});
Therefore the list is being populated with 1 adapter, but you are setting the listener on an unused second adapter.
The fix is to use the same adapter for both. If you make the adapater a field, and don't create a new one inside of logItems, but just set your listener it should work.
i.e.
// as a field in your class
private PostAdapter adapter;
then
// in `populateList()`
adapter = new PostAdapter(posts, getApplicationContext());
rvPosts.setAdapter(adapter);
and
// in `logItems()`
adapter.setListener(new AdapterCallback() {
#Override
public void onMethodCallback(int id) {
...
}
});
In Adapter
public class CustomerListAdapter extends RecyclerView.Adapter<CustomerListAdapter.OrderItemViewHolder> {
private Context mCtx;
ProgressDialog progressDialog;
//we are storing all the products in a list
private List<CustomerModel> customeritemList;
public CustomerListAdapter(Context mCtx, List<CustomerModel> orderitemList) {
this.mCtx = mCtx;
this.customeritemList = orderitemList;
progressDialog = new ProgressDialog(mCtx);
}
#NonNull
#Override
public OrderItemViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mCtx);
View view = inflater.inflate(R.layout.activity_customer_list, null);
return new OrderItemViewHolder(view, mCtx, customeritemList);
}
#Override
public void onBindViewHolder(#NonNull OrderItemViewHolder holder, int position) {
CustomerModel customer = customeritemList.get(position);
try {
//holder.textViewPINo.setText("PINo \n"+Integer.toString( order.getPINo()));
holder.c_name.setText(customer.getCustomerName());
holder.c_address.setText(customer.getAddress());
holder.c_contact.setText(customer.getMobile());
holder.i_name.setText(customer.getInteriorName());
holder.i_contact.setText(customer.getInteriorMobile());
holder.i_address.setText(customer.getAddress());
} catch (Exception E) {
E.printStackTrace();
}
}
#Override
public int getItemCount() {
return customeritemList.size();
}
class OrderItemViewHolder extends RecyclerView.ViewHolder implements View.OnLongClickListener, View.OnClickListener {
AlertDialog.Builder alert;
private Context mCtx;
TextView c_name, c_contact, c_address, i_name, i_contact, i_address;
TextView OrderItemID, MaterialType, Price2, Qty, AQty;
//we are storing all the products in a list
private List<CustomerModel> orderitemList;
public OrderItemViewHolder(View itemView, Context mCtx, List<CustomerModel> orderitemList) {
super(itemView);
this.mCtx = mCtx;
this.orderitemList = orderitemList;
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
// CatelogOrderDetailModel catelogOrderDetailModel = new CatelogOrderDetailModel();
c_name = itemView.findViewById(R.id.customerName);
c_contact = itemView.findViewById(R.id.contact);
c_address = itemView.findViewById(R.id.address);
i_name = itemView.findViewById(R.id.interiorName);
i_address = itemView.findViewById(R.id.interiorAddress);
i_contact = itemView.findViewById(R.id.interiorContact);
}
#Override
public void onClick(View v) {
int position = getAdapterPosition();
CustomerModel orderitem = this.orderitemList.get(position);
}
#Override
public boolean onLongClick(View v) {
int position = getAdapterPosition();
CustomerModel orderitem = this.orderitemList.get(position);
if (v.getId() == itemView.getId()) {
// showUpdateDeleteDialog(order);
try {
} catch (Exception E) {
E.printStackTrace();
}
Toast.makeText(mCtx, "lc: ", Toast.LENGTH_SHORT).show();
}
return true;
}
}
}
I really don't know how to do this. I have tried some tutorial but not worked for me ... i've already done the this with many Methods but unable to do this.
Here is my RecyclerView Holder
public class RecyclerViewHolders extends RecyclerView.ViewHolder implements View.OnClickListener{
public TextView countryName;
public ImageView countryPhoto;
String s;
Bitmap image;
public RecyclerViewHolders(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
countryPhoto = (ImageView)itemView.findViewById(R.id.country_photo);
}
#Override public void onClick(View view) {
Intent imageIntent = new Intent(view.getContext(),GalleryFullImage.class);
imageIntent.putExtra("id",getAdapterPosition());
view.getContext().startActivity(imageIntent);
Toast.makeText(view.getContext(), "Clicked Country Position = " + getAdapterPosition(), Toast.LENGTH_SHORT).show();
}}
Here is my Recyclerview Adapter
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewHolders> {
private ArrayList<String> arrayList;
private Context context;
public RecyclerViewAdapter(Context context, ArrayList<String> itemList) {
this.arrayList = itemList;
this.context = context;
}
#Override
public long getItemId(int position) {
return position;
}
#Override public RecyclerViewHolders onCreateViewHolder(ViewGroup parent, int viewType) {
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.gallery_item, null);
RecyclerViewHolders rcv = new RecyclerViewHolders(layoutView);
return rcv;
}
#Override public void onBindViewHolder(RecyclerViewHolders holder, int position) {
Bitmap bitmap = BitmapFactory.decodeFile(arrayList.get(position));
holder.countryPhoto.setImageBitmap(bitmap);
}
#Override public int getItemCount() {
return this.arrayList.size();
}}
Here is my GalleryActivity
public class GalleryActivity extends AppCompatActivity {
ArrayList<String> stringList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activty_gallery);
setTitle("Gallery");
stringList = new ArrayList<>();
// Be sure that this file is exist !!
String targetPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Country";
File targetDirector = new File(targetPath);
File[] files = targetDirector.listFiles();
try
{
Arrays.sort( files, new Comparator()
{
public int compare(Object o1, Object o2) {
if (((File)o1).lastModified() > ((File)o2).lastModified()) {
return -1;
} else if (((File)o1).lastModified() < ((File)o2).lastModified()) {
return +1;
} else {
return 0;
}
}
});
for (File file : files) {
stringList.add(file.getAbsolutePath());
}
}catch (Exception e)
{
Log.e("Sort Error", e.getMessage());
}
RecyclerView rView = (RecyclerView)findViewById(R.id.my_recycler_view);
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getApplicationContext(),2);
rView.setHasFixedSize(true);
rView.setLayoutManager(layoutManager);
RecyclerViewAdapter rcAdapter = new RecyclerViewAdapter(getApplicationContext(), stringList);
rView.setAdapter(rcAdapter);
}
}
You just have to apply onClickListener in you viewholder, take the clicked adapter position in integer and pass it in next your fullscreen activity
Here is the full code, hope it helps
MainActivity
public class MainActivity extends AppCompatActivity {
private final Integer image_ids[] = {
R.drawable.image1,
R.drawable.image2,
R.drawable.image3,
R.drawable.image4,
R.drawable.image5,
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recyclerview);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getApplicationContext(),gridColumnlayout);
recyclerView.setLayoutManager(layoutManager);
ArrayList<CreateList> createLists = prepareData();
MyAdapter adapter = new MyAdapter(getApplicationContext(), createLists);
recyclerView.setAdapter(adapter);
}
private ArrayList<CreateList> prepareData(){
ArrayList<CreateList> theimage = new ArrayList<>();
for(int i = 0; i< 5; i++){
CreateList createList = new CreateList();
createList.setImage_ID(image_ids[i]);
theimage.add(createList);
}
return theimage;
}
}
CreateList Class
public class CreateList {
private Integer image_id;
public Integer getImage_ID() {
return image_id;
}
public void setImage_ID(Integer android_image_url) {
this.image_id = android_image_url;
}
}
MyAdapter
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private ArrayList<CreateList> galleryList;
private Context context;
public final static String EXTRA_MESSAGE = "FullScreen Image";
public MyAdapter(Context context, ArrayList<CreateList> galleryList) {
this.galleryList = galleryList;
this.context = context;
}
#Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int i) {
return new ViewHolder(LayoutInflater.from(context).inflate(R.layout.list_item, parent, false));
}
#Override
public void onBindViewHolder(final MyAdapter.ViewHolder viewHolder, int i) {
CreateList currentList = galleryList.get(i);
Glide.with(context).load(currentList.getImage_ID()).centerCrop().crossFade().into(viewHolder.img);
viewHolder.img.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int pos = viewHolder.getAdapterPosition();
String stringID = Integer.valueOf(pos).toString();
Intent intent = new Intent(MyAdapter.this.context, FullScreen.class);
intent.putExtra(EXTRA_MESSAGE, stringID);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return galleryList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private ImageView img;
public ViewHolder(View view) {
super(view);
img = (ImageView) view.findViewById(R.id.image);
}
}
}
FullScreen Activity
public class FullScreen extends AppCompatActivity {
private final Integer image_ids[] = {
R.drawable.image1,
R.drawable.image2,
R.drawable.image3,
R.drawable.image4,
R.drawable.image5,
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_full_screen);
Intent intent = getIntent();
String message = intent.getStringExtra(MyAdapter.EXTRA_MESSAGE);
int position = Integer.parseInt(message);
ImageView imageView = (ImageView) viewItem.findViewById(R.id.imageView);
imageView.setImageResource(image_ids[position]);
}
}
list_item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="match_parent"
android:layout_height="170dp"
android:scaleType="fitXY"
android:id="#+id/image"/>
</RelativeLayout>
Since you are loading the bitmap from file in onBindViewHolder, you can just pass the path instead in onClick and decode it again in your next activity. This may require a bit of work in your case since your ViewHolder is defined separately from your RecyclerView so it does not have access to your dataset. For starters, move your ViewHolder so it can be a static nested class of your RecyclerView. Something like this:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecyclerViewHolders>
private ArrayList<String> arrayList;
....
public static class RecyclerViewHolders extends RecyclerView.ViewHolder implements View.OnClickListener{
....
#Override
public void onClick(View view) {
Intent intent = new Intent(...);
intent.putExtra("path",arrayList.get(getAdapterPosition());
/* send intent*/
}
}