Android master detail with recycler view - android

I'm learning android and I'm just new to this concept.
This is my adapter class. It shows an error saying that the CategoryList is not an enclosing class. I'm unable to understand the error. Please help me in uderstanding it. Thanks in advance.
public class CategoryAdapter extends RecyclerView.Adapter<CategoryHolder> {
private final Context context;
private final List<Category> categories;
public CategoryAdapter(Context context, List<Category> categories) {
this.context = context;
this.categories = categories;
}
#Override
public CategoryHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(context);
// Here it's showing an error: CategoryList is not an enclosing class.
return new CategoryHolder(layoutInflater, parent);
}
#Override
public void onBindViewHolder(CategoryHolder holder, int position) {
final Category category = categories.get(position);
holder.bind(category);
}
#Override
public int getItemCount() {
return categories.size();
}
}
This is my first fragment. It contains the list of categories such as google, facebook etc. On click on any of these items, it should open another fragment with some detail regarding the category.
public class CategoryList extends Fragment {
private RecyclerView recyclerView;
public CategoryList() { }
private void updateUI() {
List<Category> categories = new ArrayList<>();
categories.add(new Category(1L, "Google", "Hello world!! This is Google."));
categories.add(new Category(2L, "Facebook", "Hello world!! This is Facebook"));
categories.add(new Category(3L, "WhatsApp", "Hello world!! This is WhatsApp"));
categories.add(new Category(4L, "LinkedIn", "Hello world!! This is LinkedIn"));
CategoryAdapter categoryAdapter = new CategoryAdapter(getActivity(), categories);
recyclerView.setAdapter(categoryAdapter);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_category_list, container, false);
recyclerView = (RecyclerView) view.findViewById(R.id.category_recycler);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
updateUI();
return view;
}
public class CategoryHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private Category category;
private final TextView name;
private final TextView description;
public CategoryHolder(LayoutInflater inflater, ViewGroup parent) {
super(inflater.inflate(R.layout.category_layout, parent, false));
this.name = (TextView) itemView.findViewById(R.id.category_name);
this.description = (TextView) itemView.findViewById(R.id.category_description);
}
public void bind(final Category category) {
this.category = category;
this.name.setText(category.getName());
this.description.setText(category.getDescription());
}
#Override
public void onClick(View v) {
Fragment fragment = CategoryDetail.getInstance(category);
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
fragmentManager.beginTransaction()
.add(R.id.detail_container, fragment)
.commit();
}
}
}
This is the fragment that contains the detail of the category. For now I've not written anything in updateUI() method.
public class CategoryDetail extends Fragment {
private Category category;
public CategoryDetail() { }
public static CategoryDetail getInstance(Category category) {
CategoryDetail categoryDetail = new CategoryDetail();
categoryDetail.category = category;
return categoryDetail;
}
private void updateUI() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.category_detail, container, false);
updateUI();
return view;
}
}

You didn't create a ViewHolder class. Based on your code, you would want to create
public class CategoryHolder extends RecyclerView.ViewHolder {
public CategoryHolder(View view) {
//code for the constructor for the ViewHolder goes here.
}
}

Related

how to handle click event for each item in recyclerview child in nested recyclerview

I have a nested recyclerview to show the list of foods in each category. When the user clicks the increase or decrease button, the quantity will be updated to the quantity textview and synced to the cart stored in the database, but currently I don't know how to listen for the event when the user clicks these buttons.
Here is my current UI when run:
enter image description here
Here is my fragment:
public class TabOrderFragment extends Fragment {
private static final String ARG_RESTAURANT_ID = "restaurantId";
private int restaurantId;
View view;
RecyclerView menuRecyclerView;
RecyclerView.LayoutManager layoutManager;
ArrayList<Menu> menuArrayList;
MenuAdapter menuAdapter;
public TabOrderFragment() { }
public static TabOrderFragment newInstance(int restaurantId) {
TabOrderFragment fragment = new TabOrderFragment();
Bundle args = new Bundle();
args.putInt(ARG_RESTAURANT_ID, restaurantId);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
restaurantId = getArguments().getInt(ARG_RESTAURANT_ID);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_tab_order, container, false);
if(restaurantId != 0) {
DatabaseHandler databaseHandler = DatabaseHandler.getInstance(getActivity());
menuArrayList = new ArrayList<Menu>();
menuArrayList = databaseHandler.getAllMenuFoodsByIdRestaurant(restaurantId);
menuRecyclerView = view.findViewById(R.id.rcv_foods_menu);
menuAdapter = new MenuAdapter(getActivity().getApplicationContext(), restaurantId);
layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
menuRecyclerView.setLayoutManager(layoutManager);
menuAdapter.setData(menuArrayList);
menuRecyclerView.setAdapter(menuAdapter);
}
return view;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Log.d("TabOrderFragment", "Restaurant Id = " + restaurantId);
}
Here is my MenuAdapter:
public class MenuAdapter extends RecyclerView.Adapter<MenuAdapter.MenuViewHolder> {
Context context;
private int restaurantId;
private RecyclerView.RecycledViewPool viewPool = new RecyclerView.RecycledViewPool();
ArrayList<Menu> menuList;
public MenuAdapter(ArrayList<Menu> menuList) {
this.menuList = menuList;
}
public MenuAdapter(Context context, int restaurantId) {
this.context = context;
this.restaurantId = restaurantId;
}
public void setData(ArrayList<Menu> menuList) {
this.menuList = menuList;
notifyDataSetChanged();
}
#NonNull
#Override
public MenuViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_foods_menu, parent, false);
return new MenuViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MenuViewHolder holder, int position) {
Menu menu = menuList.get(position);
holder.txtMenuTitle.setText(menu.getTitle().concat(" (" + String.valueOf(menu.getQuantity()) + ")"));
LinearLayoutManager layoutManager = new LinearLayoutManager(holder.rcvListFoods.getContext(), LinearLayoutManager.VERTICAL, false);
layoutManager.setInitialPrefetchItemCount(menu.getFoods().size());
FoodAdapter foodAdapter = new FoodAdapter(menu.getFoods(), restaurantId);
holder.rcvListFoods.setLayoutManager(layoutManager);
holder.rcvListFoods.setAdapter(foodAdapter);
holder.rcvListFoods.setRecycledViewPool(viewPool);
}
#Override
public int getItemCount() {
if(menuList != null) {
return menuList.size();
}
return 0;
}
public class MenuViewHolder extends RecyclerView.ViewHolder {
private TextView txtMenuTitle;
private RecyclerView rcvListFoods;
public MenuViewHolder(#NonNull View itemView) {
super(itemView);
txtMenuTitle = itemView.findViewById(R.id.txv_menu_title);
rcvListFoods = itemView.findViewById(R.id.rcv_list_foods);
}
}
}
Here is my FoodAdapter:
public class FoodAdapter extends RecyclerView.Adapter<FoodAdapter.FoodViewHolder> {
private ArrayList<Food> foodList;
private int restaurantId;
private int userId;
SharedPreferences sharedPreferences;
public FoodAdapter(ArrayList<Food> foodList, int restaurantId) {
this.foodList = foodList;
this.restaurantId = restaurantId;
}
#NonNull
#Override
public FoodViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
sharedPreferences = fragmentActivity.getSharedPreferences("currentUser", Context.MODE_PRIVATE);
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_food, parent, false);
return new FoodViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull FoodViewHolder holder, int position) {
Food food =foodList.get(position);
Picasso.get().load(food.getThumbImage()).into(holder.foodThumbImage);
holder.foodName.setText(food.getName());
holder.foodDescription.setText(food.getDescription());
double price = Double.parseDouble(food.getPrice());
DecimalFormat formatter = new DecimalFormat("#,###");
holder.foodPrice.setText(formatter.format(price) + "đ");
}
#Override
public int getItemCount() {
if(foodList != null) {
return foodList.size();
}
return 0;
}
public class FoodViewHolder extends RecyclerView.ViewHolder {
private ImageView foodThumbImage;
private TextView foodName;
private TextView foodDescription;
private TextView foodPrice;
private TextView quantity;
private MaterialButton increaseBtn;
private MaterialButton decreaseBtn;
private ItemClickListener itemClickListener;
public FoodViewHolder(#NonNull View itemView) {
super(itemView);
foodThumbImage = itemView.findViewById(R.id.image_food);
foodName = itemView.findViewById(R.id.txv_food_name);
foodDescription = itemView.findViewById(R.id.txv_food_description);
foodPrice = itemView.findViewById(R.id.txv_food_price);
quantity = itemView.findViewById(R.id.txv_quantity);
increaseBtn = itemView.findViewById(R.id.btn_increase);
decreaseBtn = itemView.findViewById(R.id.btn_decrease);
}
}
in your food adapter's onBindViewHolder method use
holder.increaseBtn.setOnClickListener{
onIncreaseClick()
}
while create an interface like
interface Listener{
public void onIncreaseClick();
public void onDecreaseClick();
}
and implement your interface in your activity or fragment or viewmodel where you can listen for the click event
What you can do generally when you have something like that, is to create an interface for the interaction with the Recycler view:
interface Interaction {
public void onFoodClick(Food food)
}
Then you add an instance of this interface in your recycler view adapter, and you let your activity or fragment implement this interface, please find a good explanation here: https://stackoverflow.com/a/31671289/7334951

Sliders in fragment are not show when app run in android

The slider works but is displayed when I click on its BottomNavigationView!
i want to show after running the application without any click! in start fragment!
startFragment codes:
public class StartFragment extends Fragment {
private List<Users> users = new ArrayList<>();
private List<Product> products = new ArrayList<>();
private Activity activity;
private List<String> sliderImages = new ArrayList<>();
private SliderView sliderView;
private RecyclerView homeRecyclerView;
private RecyclerView.LayoutManager manager;
private RecyclerView.Adapter productAdapter;
public StartFragment(Activity activity, List<Users> users, List<Product> products, List<String> sliderImages) {
this.activity = activity;
this.products = products;
this.users = users;
this.sliderImages = sliderImages;
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.frame_start , container ,false);
init(rootView);
return rootView;}
private void init(ViewGroup rootView) {
bindView(rootView);
fillSliderData();
getProducts();
}
private void bindView(ViewGroup rootView) {
sliderView = rootView.findViewById(R.id.slider);
homeRecyclerView = rootView.findViewById(R.id.homeRecyclerView);
manager = new GridLayoutManager(activity,1);
homeRecyclerView.setLayoutManager(manager);
}
private void fillSliderData(){
final StartSliderAdapter startSliderAdapter = new StartSliderAdapter(activity , sliderImages);
sliderView.setSliderAdapter(startSliderAdapter);
sliderView.setIndicatorAnimation(IndicatorAnimationType.WORM);
sliderView.setSliderTransformAnimation(SliderAnimations.DEPTHTRANSFORMATION);
sliderView.startAutoCycle();
}
private void getProducts(){
productAdapter = new ProductListAdapter(activity,products,activity , users);
homeRecyclerView.setAdapter(productAdapter);
}
}
users, product and SliderImages getting from database with Volly!
slider adapter codes:
public class StartSliderAdapter extends SliderViewAdapter<StartSliderAdapter.myHolder>{
List<String> images ;
private Context context;
public StartSliderAdapter(Context context , List<String> images){
this.images = images;
this.context = context;
}
#Override
public myHolder onCreateViewHolder(ViewGroup parent) {
View view = LayoutInflater.from(context)
.inflate(R.layout.slider_item , parent , false);
StartSliderAdapter.myHolder holder = new StartSliderAdapter.myHolder(view);
return holder;
}
#Override
public void onBindViewHolder(myHolder viewHolder, int position) {
byte[] bytes = Base64.decode(images.get(position) , Base64.DEFAULT);
Bitmap i = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
viewHolder.imageView.setImageBitmap(i);
}
#Override
public int getCount() {
return images.size();
}
public class myHolder extends SliderViewAdapter.ViewHolder{
private ImageView imageView;
public myHolder(View view) {
super(view);
imageView =(ImageView) view.findViewById(R.id.startSliderImages);
}
}
}
first image
after click again
Can you tell me my mistake and guide me?
Try and use OnViewCreated instead of private void init(ViewGroup rootView)
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) { {
bindView(rootView);
fillSliderData();
getProducts();
}

RecyclerView on a fragment

i am trying to add a recyclerview on a fragment
fragments code:
public class MediaPlayerController extends Fragment{
private static final String TAG = "MediaPlayerController";
private RecyclerView recyclerViewb;
private RecycleViewAdapter myAdapter;
private ArrayList<String> myRecordings = new ArrayList<>();
//private DBHelper dbHelper;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
Log.d(TAG, "onCreateView: started");
View v = inflater.inflate(R.layout.media_player_area, container, false);
recyclerViewb = (RecyclerView)v.findViewById(R.id.recyclerViewXml);
//dbHelper = new DBHelper(v.getContext(), null, null, 1);
myRecordings.add("hau");
myRecordings.add("hau2");
myRecordings.add("hau3");
myRecordings.add("hau4");
myRecordings.add("ha5");
myRecordings.add("hau23");
myRecordings.add("ha31u");
myRecordings.add("haudsa");
System.out.println("what does this print?"+myRecordings);
myAdapter = new RecycleViewAdapter(v.getContext(), myRecordings);
recyclerViewb.setAdapter(myAdapter);
recyclerViewb.setLayoutManager(new LinearLayoutManager(v.getContext()));
Log.d(TAG, "onCreateView: returned");
return v;
}
in the logs i see that that it doesn't even get to the RecycleViewAdapter sections of code at all the fragment is completely blank
i get not errors as well
public class RecycleViewAdapter extends RecyclerView.Adapter<RecycleViewAdapter.ViewHolder>{
private static final String TAG = "RecycleViewAdapter";
private Context mContext;
private ArrayList<String> mRecName = new ArrayList<>();
public RecycleViewAdapter(Context mContext, ArrayList<String> mRecName) {
this.mContext = mContext;
this.mRecName = mRecName;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
Log.d(TAG, "onCreateViewHolder: i am here");
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_row_recycle, parent, false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder holder, int position) {
Log.d(TAG, "onBindViewHolder: called");
holder.recTxt.setText(mRecName.get(position).toString());
holder.parentLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(mContext, "sas gamaw", Toast.LENGTH_LONG);
}
});
}
#Override
public int getItemCount() {
return 0;
}
public class ViewHolder extends RecyclerView.ViewHolder{
RelativeLayout parentLayout;
TextView recTxt;
public ViewHolder(View itemView) {
super(itemView);
recTxt = itemView.findViewById(R.id.recTextView);
parentLayout = itemView.findViewById(R.id.parentLayoutXml);
}
}
}
in the logs it only displays oncreateView started and the myRecordings arraylist
onCreateView: started
I/System.out: what does this print?[hau, hau2, hau3, hau4, ha5,
hau23, ha31u, haudsa]
MediaPlayerController: onCreateView: returned
i can't think of what is going wrong :/ please help out
i also want to add that i am fairly new to android studio thanks
your code problem it is in Recycler Adapter in getItemCount() method,
You don't return any Item , you must change it to :
#Override
public int getItemCount() {
return mRecName.size();
}

How do display data from Parse.com to android recycler-view?

I am trying to pull data from Parse.com cloud to my android application.This is the code for my custom adapter:
public class AdvertisingAdapter extends RecyclerView.Adapter<AdvertisingAdapter.TatsViewHolder> {
List<AdvertInfo> data = new ArrayList<>();
private LayoutInflater inflater;
public AdvertisingAdapter(Context context, List<AdvertInfo> data){
inflater = LayoutInflater.from(context);
this.data = data;
}
#Override
public TatsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.single_ad, parent, false);
TatsViewHolder holder = new TatsViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(TatsViewHolder holder, int position) {
AdvertInfo current = data.get(position);
holder.daPoster.setText(current.theadvertiser);
holder.daAdvert.setText(current.theadvert);
}
#Override
public int getItemCount() {
return data.size();
}
class TatsViewHolder extends RecyclerView.ViewHolder{
TextView daPoster;
TextView daAdvert;
public TatsViewHolder(View itemView) {
super(itemView);
daPoster = (TextView)itemView.findViewById(R.id.txtAdvertiser);
daAdvert = (TextView)itemView.findViewById(R.id.txtAdvert);
}
}
}
and the code for my member class
public class AdvertInfo {
public String theadvertiser;
public String theadvert;
}
then for my fragment where i am displaying the data here is the code
public class ViewAdverts extends android.support.v4.app.Fragment {
private RecyclerView myRecyclerView;
AdvertisingAdapter myAdapter;
public ViewAdverts() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View layout = inflater.inflate(R.layout.view_adverts, container, false);
myRecyclerView = (RecyclerView)layout.findViewById(R.id.advert_list);
myAdapter = new AdvertisingAdapter(getActivity(), getData());
myRecyclerView.setAdapter(myAdapter);
myRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
return layout;
}
public static List<AdvertInfo> getData(){
final List<AdvertInfo> myposts = new ArrayList<>();
ParseQuery<Posts> query = ParseQuery.getQuery(Posts.class);
query.findInBackground(new FindCallback<Posts>() {
#Override
public void done(List<Posts> list, ParseException e) {
if (e == null){
for (int i = 0; i < list.size(); i++){
AdvertInfo ad = new AdvertInfo();
ad.theadvertiser = list.get(i).getString(ParseConstants.ADVERTISER);
ad.theadvert = list.get(i).getString(ParseConstants.DESCRIPTION);
myposts.add(ad);
}
}
}
});
return myposts;
}
}
I have tried to debug by putting breaks on getData method in the fragment I am get the data but I dont know why my recycler view appearing empty when I run.

Values from RecyclerView item to other Activity

I'm trying to send values from a RecyclerView Item with X position, to other activity which displays those values, for example, in my RecyclerView my X item, has an Image, a Title and a Subtitle; and I want onClick to be displayed in other activity that Image, Title and Subtitle. By that way for the rest of my items.
I think it should be done with putExtra but I can´t get it.
Here is my Adapter with ViewHolder:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.myViewHolder> {
private LayoutInflater inflater;
private List<Data> info = Collections.emptyList();
private Context context;
public MyAdapter (Context context, List<Data> info){
this.context=context;
inflater = LayoutInflater.from(context);
this.info = info;
}
#Override
public myViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.recycler_item, parent, false);
myViewHolder holder = new myViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(myViewHolder holder, int position) {
Data current = info.get(position);
holder.title.setText(current.title);;
holder.subtitle.setText(current.subtitle);
holder.image.setImageResource(current.imagenId);
}
#Override
public int getItemCount() {
return info.size();
}
class myViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView image;
TextView title;
TextView subtitle;
public myViewHolder(View itemView) {
super(itemView);
image = (ImageView) itemView.findViewById(R.id.Image1);
title = (TextView) itemView.findViewById(R.id.TextTitle);
subtitle = (TextView) itemView.findViewById(R.id.TextSubTitle);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
Intent intent = new Intent(context,ItemSelection.class);
context.startActivity(intent);
}
}
}
Here is the activity of my fragment where the RecyclerView is shown:
public class ltfg0 extends Fragment {
private RecyclerView recyclerView;
private MyAdapter adapter;
public ltfg0() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_ltfg0, container, false);
recyclerView = (RecyclerView) view.findViewById(R.id.ltfg0);
adapter = new MyAdapter(getActivity(),getInfo());
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
return view;
}
public static List<Data> getInfo(){
List<Data> info = new ArrayList<>();
int[] srcs = {R.mipmap.img1, R.mipmap.img2, R.mipmap.img3, R.mipmap.img4};
String[] titles = {"Title 1", "Title 2", "Title 3", "Title 4"};
String[] subtitles = {"Description 1", "Description 2", "Description 3", "Description 4"};
for (int i=0; i<srcs.length && i<titles.length && i<subtitles.length;i++){
Data current = new Data();
current.imagenId = srcs[i];
current.title = titles[i];
current.subtitle = subtitles[i];
info.add(current);
}
return info;
}
}
And my Data class:
public class Data {
public int imagenId;
public String title;
public String subtitle;
}
You can do it like this inside your ViewHolder:
#Override
public void onClick(View view) {
Intent intent = new Intent(context,ItemSelection.class);
Bundle bundle = new Bundle();
bundle.putSerializable("DATA",info.get(getAdapterPosition()));
intent.putExtras(bundle);
context.startActivity(intent);
}
Then retrieve your instance in your Activity#onCreate() via getIntent():
Data data = (Data)getIntent().getExtras().getSerializable("DATA");
//if you have a TextView, for example...
yourTextView.setText(data.getTitle());
Off course, your Data class must implement Serializable:
public class Data implements Serializale { ...

Categories

Resources