I'm trying to inflate json data onto my List Item and I'm getting a blank Screen. The data I'm trying to show is from a nested json array. So I have created to Objects using retrofit and gson. I have made 2 objects (Cake and Ingredients) and the ingredients is a of List<> type.I have also provided an image of the json file.
public class CakesItem {
#SerializedName("id")
private int mId;
#SerializedName("name")
private String mName;
#SerializedName("ingredients")
private List<Ingredient> mIngredients;
public int getmId() {
return mId;
}
public String getmName() {
return mName;
}
public List<Ingredient> getmIngredients() {
return mIngredients;
}
}
public class Ingredient implements Parcelable {
private double quantity;
private String measure, ingredient;
public String getmMeasure() {
return measure;
}
public double getmQuantity() {
return quantity;
}
public String getmIngredient() {
return ingredient;
}
}
public class IngredientsAdapter extends RecyclerView.Adapter<IngredientsAdapter.IngredientsHolder> {
private List<Ingredient> ingredients = new ArrayList<>();
#NonNull
#Override
public IngredientsHolder onCreateViewHolder(#NonNull ViewGroup parent, int i) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.ingredient_list_item, parent, false);
return new IngredientsHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final IngredientsHolder Holder, int position) {
Holder.onBind(ingredients.get(position));
}
#Override
public int getItemCount() {
return ingredients.size();
}
void getIngredientsData(List<Ingredient> ingredients) {
this.ingredients.clear();
this.ingredients = ingredients;
notifyDataSetChanged();
}
class IngredientsHolder extends RecyclerView.ViewHolder {
private final TextView mIngredientsTV;
IngredientsHolder(#NonNull View itemView) {
super(itemView);
mIngredientsTV = itemView.findViewById(R.id.ingredients_list_tv);
}
void onBind(Ingredient ingredients) {
mIngredientsTV.setText(formatString(ingredients.getmIngredient(), String.valueOf(ingredients.getmQuantity()), ingredients.getmMeasure()));
}
private String formatString(String i, String q, String m) {
return " (" + q + " " + m + ") " + i;
}
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recipe_detail);
mIngredientsList = new ArrayList<>();
IngredientsAdapter ingredientsAdapter = new IngredientsAdapter();
ingredientsRecyclerView = findViewById(R.id.ingredients_recycler_view);
ingredientsRecyclerView.setHasFixedSize(true);
ingredientsRecyclerView.setLayoutManager(new LinearLayoutManager(this));
ingredientsRecyclerView.setAdapter(ingredientsAdapter);
ingredientsAdapter.getIngredientsData(mIngredientsList);
mRecipeImage = findViewById(R.id.recipe_cake_image_iv);
Drawable myDrawable = getResources().getDrawable(R.drawable.nutella_pie_2);
mRecipeImage.setImageDrawable(myDrawable);
mCakeTitle = findViewById(R.id.cake_title);
mCakeTitle.setText("Nutella Pie");
}
Where do you parse the JSON to object? From the code you just set an empty list to your adapter.
Try:
In MainActivity:
#Override
public void onItemClicked(CakesItem cakesItem) {
Intent detailIntent = new Intent(this, recipe_detail.class);
detailIntent.putExtra("Ingredients", cakesItem.getmIngredients());
startActivity(detailIntent);
}
In recipe_detail:
private List<Ingredient> mIngredientsList = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
...
mIngredientsList = getIntent().getSerializableExtra("Ingredients");;
IngredientsAdapter ingredientsAdapter = new IngredientsAdapter();
ingredientsAdapter.getIngredientsData(mIngredientsList);
...
}
Related
I am using Android Paging with Room Database.I am going to fetch data using retrofit.But I am getting error No adapter attached; skipping layout.I searched a lot but dont find solution for this. Base url is working, for security reason i just hide base url.
private StoreAdapter storeAdapter;
private Store_ViewModel store_viewModel;
private RecyclerView recyclerView;
private static final String URL_DATA="https://xxxx/";
//insertion
private Store_Repository store_repository;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
store_repository=new Store_Repository(getApplication());
//adapter
storeAdapter=new StoreAdapter(getApplicationContext(), this);
//recycler
recyclerView=findViewById(R.id.recycler_store);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
store_viewModel=new ViewModelProvider(this).get(Store_ViewModel.class);
store_viewModel.pagedListLiveData.observe(this, new Observer<PagedList<StoreModel>>() {
#Override
public void onChanged(PagedList<StoreModel> storeModels) {
storeAdapter.submitList(storeModels);
recyclerView.setAdapter(storeAdapter);
}
});
getAllProducts();
}
private void getAllProducts() {
Retrofit retrofit=new Retrofit.Builder()
.baseUrl(URL_DATA)
.addConverterFactory(GsonConverterFactory.create())
.build();
//calling api
Api api=retrofit.create(Api.class);
Call<List<StoreModel>>call=api.getAllProducts();
call.enqueue(new Callback<List<StoreModel>>() {
#Override
public void onResponse(Call<List<StoreModel>> call, Response<List<StoreModel>> response) {
if (response.isSuccessful())
{
store_repository.insert(response.body());
}
}
#Override
public void onFailure(Call<List<StoreModel>> call, Throwable t) {
Toast.makeText(MainActivity.this, "Something get Wrong", Toast.LENGTH_SHORT).show();
}
});
}
This is my ViewModel Class
public class Store_ViewModel extends AndroidViewModel {
public LiveData<PagedList<StoreModel>>pagedListLiveData;
private StoreDao storeDao;
public Store_ViewModel(#NonNull Application application) {
super(application);
storeDao= StoreDatabase.getINSTANCE(application).storeDao();
pagedListLiveData=new LivePagedListBuilder<>(
storeDao.getAllItems(),5
).build();
}
}
And this is my adapter class
public class StoreAdapter extends PagedListAdapter<StoreModel,StoreAdapter.StoreViewHolder> {
private Context context;
private static Listener listener;
public StoreAdapter(Context context,Listener listener)
{
super(storeModelItemCallback);
this.context=context;
this.listener=listener;
}
#NonNull
#Override
public StoreViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return null;
}
#Override
public void onBindViewHolder(#NonNull StoreViewHolder holder, int position) {
StoreModel storeModel=getItem(position);
holder.Product_name.setText(storeModel.getProduct_name());
holder.Product_weight.setText(storeModel.getProduct_weight());
holder.Price.setText(storeModel.getPrice());
holder.Mrp.setText(storeModel.getMrp());
}
static class StoreViewHolder extends RecyclerView.ViewHolder
{
TextView Product_name;
TextView Product_weight;
TextView Price;
TextView Mrp;
public StoreViewHolder(#NonNull View itemView) {
super(itemView);
Product_name=itemView.findViewById(R.id.product_name);
Product_weight=itemView.findViewById(R.id.product_weight);
Price=itemView.findViewById(R.id.price);
Mrp=itemView.findViewById(R.id.mrp);
//listener
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onItemCLickListener(getAdapterPosition());
}
});
}
}
static DiffUtil.ItemCallback<StoreModel> storeModelItemCallback=new DiffUtil.ItemCallback<StoreModel>() {
#Override
public boolean areItemsTheSame(#NonNull StoreModel oldItem, #NonNull StoreModel newItem) {
return oldItem.getDatabase_id()==newItem.getDatabase_id();
}
#SuppressLint("DiffUtilEquals")
#Override
public boolean areContentsTheSame(#NonNull StoreModel oldItem, #NonNull StoreModel newItem) {
return oldItem.equals(newItem);
}
};
Json Response from Server
{"status":1,"msg":"",
"paginate":{"limit":1000,"PageNo":1},
"data":
[
{
"product_id":23234,
"product_brand_id":130,
"product_name":"Xyz"
,"product_code":"1554729666482",
"mrp":5,
"price":4,
"product_weight":1,
"product_weight_unit":"PCS"
}
,{"product_id":23244,
"product_brand_id":130,
"product_name":"Abc - 100 Gms",
"product_code":"9A","mrp":38,"price":31.94,
"product_weight":100,"product_weight_unit":"GM"}
ApiInterface
public interface Api {
#GET("/get-products")
Call<List<StoreModel>>getAllProducts();
}
Below is my StoreModel in which i am using room database fro creating tables
#Entity(tableName = "store",indices = #Index(value="product_id",unique = true))
public class StoreModel {
#PrimaryKey(autoGenerate = true)
private int database_id;
#SerializedName("product_id")
private int product_id;
#SerializedName("product_brand_id")
private int product_brand_id;
#SerializedName("product_name")
private String product_name;
#SerializedName("product_code")
private int product_code;
#SerializedName("mrp")
private int mrp;
#SerializedName("price")
private int price;
#SerializedName("product_weight")
private int product_weight;
#SerializedName("product_weight_unit")
private String product_weight_unit;
public StoreModel() {
}
public StoreModel(int product_id, int product_brand_id, String product_name, int product_code, int mrp, int price, int product_weight, String product_weight_unit) {
this.product_id = product_id;
this.product_brand_id = product_brand_id;
this.product_name = product_name;
this.product_code = product_code;
this.mrp = mrp;
this.price = price;
this.product_weight = product_weight;
this.product_weight_unit = product_weight_unit;
}
public int getProduct_id() {
return product_id;
}
public void setProduct_id(int product_id) {
this.product_id = product_id;
}
public int getProduct_brand_id() {
return product_brand_id;
}
public void setProduct_brand_id(int product_brand_id) {
this.product_brand_id = product_brand_id;
}
public String getProduct_name() {
return product_name;
}
public void setProduct_name(String product_name) {
this.product_name = product_name;
}
public int getProduct_code() {
return product_code;
}
public void setProduct_code(int product_code) {
this.product_code = product_code;
}
public int getMrp() {
return mrp;
}
public void setMrp(int mrp) {
this.mrp = mrp;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public int getProduct_weight() {
return product_weight;
}
public void setProduct_weight(int product_weight) {
this.product_weight = product_weight;
}
public String getProduct_weight_unit() {
return product_weight_unit;
}
public void setProduct_weight_unit(String product_weight_unit) {
this.product_weight_unit = product_weight_unit;
}
public int getDatabase_id() {
return database_id;
}
public void setDatabase_id(int database_id) {
this.database_id = database_id;
}
}
Below is Dao class
#Dao
public interface StoreDao {
#Insert(onConflict = OnConflictStrategy.REPLACE)
void insert(List<StoreModel> storeModels);
#Query("DELETE FROM store")
void deleteAll();
#Query("SELECT * FROM store ORDER BY database_id ASC")
DataSource.Factory<Integer,StoreModel>getAllItems();
}
Set recyclerView.setAdapter(storeAdapter); outside of observer because each time data is observed it will set adapter. So, adapter is attached to recyclerView only once. Like
recyclerView.setAdapter(storeAdapter);
store_viewModel.pagedListLiveData.observe(this, new Observer<PagedList<StoreModel>>() {
#Override
public void onChanged(PagedList<StoreModel> storeModels) {
storeAdapter.submitList(storeModels);
//recyclerView.setAdapter(storeAdapter);
}
});
From the API you are not getting exactly the StoreModel as response. You are getting another object which is StoreModel is a child object. You have to create resposne object like below:
public class ResponseObject{
//#SerializedName("status")
//private int status;
#SerializedName("data")
private List<StoreModel> storeModelList;
//getters and setters goes here
}
And then your interface should be like below as you are expecting
ResponseObject here
public interface Api {
#GET("/get-products")
Call<ResponseObject> getAllProducts();
}
Those are categories and subcategories. There can be subcategory or not.
JsonCode to be used is as below.
categoryId is what will change to call subcategories.
E.g. If you want to see subcategories of cars
Json Code
[{"Id":1,"TitleEN":"Cars","TitleAR":"سيارات","Photo":"http://souq.hardtask.co//Files/CategoryPhotos/ce686544-9f51-4213-b5db-7c015b788e8d.png","ProductCount":"3","HaveModel":"0","SubCategories":[{"Id":6,"TitleEN":"Cat6","TitleAR":"قسم6","Photo":"http://souq.hardtask.co//Files/CategoryPhotos/ce686544-9f51-4213-b5db-7c015b788e8d.png","ProductCount":"3","HaveModel":"0","SubCategories":[]}]},{"Id":2,"TitleEN":"Cat2","TitleAR":"قسم2","Photo":"http://souq.hardtask.co//Images/no_image.png","ProductCount":"8","HaveModel":"0","SubCategories":[{"Id":13,"TitleEN":"cat1 -1 ","TitleAR":"cat1 - 1","Photo":"http://souq.hardtask.co//Images/no_image.png","ProductCount":"8","HaveModel":"0","SubCategories":[]}]},{"Id":3,"TitleEN":"Cat3","TitleAR":"قسم3","Photo":"http://souq.hardtask.co//Images/no_image.png","ProductCount":"2","HaveModel":"0","SubCategories":[]},{"Id":4,"TitleEN":"Cat4","TitleAR":"قسم4","Photo":"http://souq.hardtask.co//Images/no_image.png","ProductCount":"1","HaveModel":"0","SubCategories":[]},{"Id":5,"TitleEN":"Cat5","TitleAR":"قسم5","Photo":"http://souq.hardtask.co//Images/no_image.png","ProductCount":"0","HaveModel":"0","SubCategories":[]},{"Id":8,"TitleEN":"Cat8","TitleAR":"قسم8","Photo":"http://souq.hardtask.co//Images/no_image.png","ProductCount":"0","HaveModel":"0","SubCategories":[]},{"Id":9,"TitleEN":"Slide01","TitleAR":"Slide02","Photo":"http://souq.hardtask.co//Files/CategoryPhotos/2ba07cb2-49a0-47e4-aba6-ef10a916fb12.png","ProductCount":"0","HaveModel":"0","SubCategories":[]}]
ImageAdapter
public class ImageAdapter extends BaseAdapter {
private Context mContext;
public ImageAdapter(Context c){
mContext = c;
}
#Override
public int getCount(){
return images.size();
}
#Override
public Object getItem(int position){
return images.get(position);
}
public long getItemId(int position){
return 0;
}
public View getView(int position, View convertView, ViewGroup parent){
ImageView imageview;
if (convertView == null){
imageview = new ImageView(mContext);
imageview.setPadding(0, 0, 0, 0);
//imageview.setLayoutParams(new GridLayout.MarginLayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
imageview.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
imageview.setAdjustViewBounds(true);
} else {
imageview = (ImageView) convertView;
}
Picasso.with(mContext).load(images.get(position)).placeholder(R.mipmap.ic_launcher).into(imageview);
return imageview;
}
/*
Custom methods
*/
public void addItem(String url){
images.add(url);
}
public void clearItems() {
images.clear();
}
public ArrayList<String> images = new ArrayList<String>();
}
Movie Model
public class Movie implements Parcelable {
public String TitleEN;
public String TitleAR;
public String Photo;
public int id;
public Movie(){
}
protected Movie(Parcel in) {
TitleEN = in.readString();
TitleAR = in.readString();
Photo = in.readString();
id = in.readInt();
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(TitleEN);
dest.writeString(TitleAR);
dest.writeString(Photo);
dest.writeInt(id);
}
#SuppressWarnings("unused")
public static final Parcelable.Creator<Movie> CREATOR = new Parcelable.Creator<Movie>() {
#Override
public Movie createFromParcel(Parcel in) {
return new Movie(in);
}
#Override
public Movie[] newArray(int size) {
return new Movie[size];
}
};
}
Fragament_main
public class Fragament_main extends Fragment {
public View mainFragmentView;
public String LOG_TAG = "ShowcaseFragment";
public ArrayList<Movie> movies = new ArrayList<Movie>();
private RequestQueue mRequestQueue;
public ImageAdapter imageAdapter;
public static Fragament_main instance;
GridView gridview;
public boolean isDualPane = false;
// static to preserve sorting over orientation changes (activity restart)
public static String sortOrder = "popularity.desc", moreParams = "";
public static boolean setting_cached = false;
public int gridPos = -1;
public Fragament_main() {
// Required empty public constructor
instance = this;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mainFragmentView = inflater.inflate(R.layout.fragment_main, container, false);
mRequestQueue = Volley.newRequestQueue(getContext());
// setup adapters
imageAdapter = new ImageAdapter(getContext());
gridview = (GridView) mainFragmentView.findViewById(R.id.gridView);
gridview.setAdapter(imageAdapter);
//updateUI(setting_cached);
//gridview.setOnItemClickListener(new GridClickListener());
// manage grid col count wrt Orientation
if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)
setGridColCount(3);
else
setGridColCount(2);
return mainFragmentView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("GRIDVIEW_POSITION", gridview.getFirstVisiblePosition());
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null)
gridPos = savedInstanceState.getInt("GRIDVIEW_POSITION");
}
#Override
public void onDestroyView() {
super.onDestroyView();
mRequestQueue.cancelAll(new RequestQueue.RequestFilter() {
#Override
public boolean apply(Request<?> request) {
return true;
}
});
}
/*class GridClickListener implements AdapterView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
if (isDualPane){
android.support.v4.app.FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
DetailActivityFragment detailActivityFragment = DetailActivityFragment.newInstance(movies.get(position));
ft.replace(R.id.detailContainer, detailActivityFragment);
ft.commit();
} else {
Intent intent = new Intent(getContext(), DetailActivity.class);
intent.putExtra(Intent.EXTRA_TEXT, (Parcelable) movies.get(position));
startActivity(intent);
}
}
}*/
/* public void updateUI(boolean cached){
movies.clear();
imageAdapter.clearItems();
setting_cached = cached;
if (!cached)
getMovies(sortOrder, moreParams);
else
getFavorites();
}
*/
public void getMovies(String sortOrder, String moreParams){
String url = "http://souq.hardtask.co/app/app.asmx/GetCategories?categoryId=0&countryId=1";
JsonObjectRequest req = new JsonObjectRequest(url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray items = response.getJSONArray("results");
JSONObject movieObj;
for (int i=0; i<items.length(); i++){
movieObj = items.getJSONObject(i);
Movie movie = new Movie();
movie.id = movieObj.getInt("id");
movie.TitleEN = movieObj.getString("original_title");
movie.TitleAR = movieObj.getString("overview");
movie.Photo = "http://souq.hardtask.co/app/app.asmx/GetCategories?categoryId=0&countryId=1" + movieObj.getString("poster_path");
movies.add(movie);
// Add image to adapter
imageAdapter.addItem(movie.Photo);
}
} catch (JSONException e){
e.printStackTrace();
}
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
gridview.setAdapter(imageAdapter);
if (gridPos > -1)
gridview.setSelection(gridPos);
gridPos = -1;
}
});
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(LOG_TAG, "Error in JSON Parsing");
}
});
mRequestQueue.add(req);
}
/* public void getFavorites(){
movies.addAll((new MoviesDB()).getFavoriteMovies(getContext().getContentResolver()));
for (Movie movie : movies){
imageAdapter.addItem(movie.Photo);
}
gridview.setAdapter(imageAdapter);
if (gridPos > -1)
gridview.setSelection(gridPos);
gridPos = -1;
}*/
public void updateFavoritesGrid(){
if (setting_cached) {
int p = gridview.getLastVisiblePosition();
///updateUI(true);
gridview.smoothScrollToPosition(p);
}
}
public void setGridColCount(int n){
((GridView) mainFragmentView.findViewById(R.id.gridView)).setNumColumns(n);
}
}
I don't know how to add Json data into GridView.
Could you help me?
Go through this example to view images in grid,
Convert your jsonArray into an ArrayList by using,
ArrayList<Cars> carsList = new Gson().fromJson(jsonArrayYouHave.toString(),new TypeToken<List<Cars>>() {
}.getType());
Pass this Array to your Adapter.
Use this POJO,
public class Cars {
private String TitleAR;
private String HaveModel;
private String TitleEN;
private String Id;
private ArrayList<SubCategories> SubCategories;
private String Photo;
private String ProductCount;
//Todo please add getter/setters for class Cars variables here
public class SubCategories {
private String TitleAR;
private String HaveModel;
private String TitleEN;
private String Id;
private ArrayList<String> SubCategories;
private String Photo;
private String ProductCount;
//Todo please add getter/setters for class SubCategories variables here
}
I'll suggest to use Retrofit as it'll provide you parsed arraylist which is converted into Response POJO you have provided. You can find many examples for Retrofit.
Step 1
Add the following dependencies in your app level gradle file.Dependencies are for retrofit, gsonConvertor butterknife and glide.
implementation 'com.squareup.retrofit2:retrofit:2.1.0'
implementation 'com.google.code.gson:gson:2.6.2'
implementation 'com.squareup.retrofit2:converter-gson:2.1.0'
implementation('com.squareup.retrofit2:retrofit:2.1.0') {
// exclude Retrofit’s OkHttp dependency module and define your own module import
exclude module: 'okhttp'
}
implementation 'com.google.code.gson:gson:2.6.2'
implementation 'com.squareup.retrofit2:converter-gson:2.1.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.4.1'
implementation 'com.squareup.okhttp3:okhttp:3.4.1'
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation "com.jakewharton:butterknife:$BUTTER_KNIFE_VERSION"
annotationProcessor "com.jakewharton:butterknife-compiler:$BUTTER_KNIFE_VERSION"
implementation 'com.github.bumptech.glide:glide:4.8.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'
Step 2 Create a class by name ApiClient and paste the following code in this class
public class ApiClient {
private static Retrofit retrofit = null;
public static Retrofit getRetrofit() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
retrofit = new Retrofit.Builder()
.baseUrl("http://souq.hardtask.co")
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
return retrofit;
}
}
Step 3 Create a new Interface class by name APIInterface and paste the following code in this class
#GET("/app/app.asmx/GetCategories")
Call<List<Product>> getProducts(#QueryMap Map<String, String> params);
Step 4 Create POJO classes according to json response. We have two classes Products and their subcategory.So I am creating first class by name Product
public class Product {
#SerializedName("Id")
#Expose
private Integer id;
#SerializedName("TitleEN")
#Expose
private String titleEN;
#SerializedName("TitleAR")
#Expose
private String titleAR;
#SerializedName("Photo")
#Expose
private String photo;
#SerializedName("ProductCount")
#Expose
private String productCount;
#SerializedName("HaveModel")
#Expose
private String haveModel;
#SerializedName("SubCategories")
#Expose
private List<SubCategory> subCategories = null;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitleEN() {
return titleEN;
}
public void setTitleEN(String titleEN) {
this.titleEN = titleEN;
}
public String getTitleAR() {
return titleAR;
}
public void setTitleAR(String titleAR) {
this.titleAR = titleAR;
}
public String getPhoto() {
return photo;
}
public void setPhoto(String photo) {
this.photo = photo;
}
public String getProductCount() {
return productCount;
}
public void setProductCount(String productCount) {
this.productCount = productCount;
}
public String getHaveModel() {
return haveModel;
}
public void setHaveModel(String haveModel) {
this.haveModel = haveModel;
}
public List<SubCategory> getSubCategories() {
return subCategories;
}
public void setSubCategories(List<SubCategory> subCategories) {
this.subCategories = subCategories;
}
}
And SubCategory
public class SubCategory {
#SerializedName("Id")
#Expose
private Integer id;
#SerializedName("TitleEN")
#Expose
private String titleEN;
#SerializedName("TitleAR")
#Expose
private String titleAR;
#SerializedName("Photo")
#Expose
private String photo;
#SerializedName("ProductCount")
#Expose
private String productCount;
#SerializedName("HaveModel")
#Expose
private String haveModel;
#SerializedName("SubCategories")
#Expose
private List<Object> subCategories = null;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitleEN() {
return titleEN;
}
public void setTitleEN(String titleEN) {
this.titleEN = titleEN;
}
public String getTitleAR() {
return titleAR;
}
public void setTitleAR(String titleAR) {
this.titleAR = titleAR;
}
public String getPhoto() {
return photo;
}
public void setPhoto(String photo) {
this.photo = photo;
}
public String getProductCount() {
return productCount;
}
public void setProductCount(String productCount) {
this.productCount = productCount;
}
public String getHaveModel() {
return haveModel;
}
public void setHaveModel(String haveModel) {
this.haveModel = haveModel;
}
public List<Object> getSubCategories() {
return subCategories;
}
public void setSubCategories(List<Object> subCategories) {
this.subCategories = subCategories;
}
}
Step 5 now we need a view for recyclerview holder(in your case gridview layout). For that we need to create a new layout file inside layout folder. you can name it li_product_view
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="200dp"
android:layout_height="200dp">
<ImageView
android:id="#+id/ImageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#mipmap/ic_launcher" />
<TextView
android:id="#+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#id/ImageView"
android:layout_alignTop="#id/ImageView"
android:layout_alignRight="#id/ImageView"
android:layout_alignBottom="#id/ImageView"
android:text="#string/app_name"
android:gravity="bottom|right" />
</RelativeLayout>
</RelativeLayout>
Step 6 Now we need itemHolder to hold the view for that purpose we will create a new class by name ProductsItemHolderand will have the following code
public class ProductsItemHolder extends RecyclerView.ViewHolder {
#BindView(R.id.ImageView)
ImageView imageView;
#BindView(R.id.tv_title)
TextView textView;
public ProductsItemHolder(#NonNull View itemView) {
super(itemView);
ButterKnife.bind(this,itemView);
}
public void bindData(Product datum, int position, int size) {
Glide.with(itemView)
.asBitmap()
.load(datum.getPhoto())
.into(imageView);
textView.setText(datum.getTitleAR());
}
}
Step 7 Now we need adapter which contains the data to present inside recyclerview. Create a new class by name ProductsAdapter and paste the following code inside this class
public class ProductsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<Product> mList;
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.li_product_view, viewGroup, false);
return new ProductsItemHolder(view);
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder viewHolder, int position) {
int size= mList.size();
((ProductsItemHolder) viewHolder).bindData(mList.get(position), position,size);
}
#Override
public int getItemCount() {
return mList.size();
}
public void setData(List<Product> userLists) {
this.mList = userLists;
notifyDataSetChanged();
}
}
Step 8 now inside the activity or fragment we need to get response from json and pass this response to recyclerview.
public class MainActivity extends AppCompatActivity {
APIInterface apiInterfacePages;
RecyclerView recyclerView;
List<MultipleResource.Datum> datumList= new ArrayList<>();
ProgressDialog dialog;
ProductsAdapter productsAdapter;
private List<Product> dataArrayList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
apiInterfacePages= PageApiClient.getRetrofit().create(APIInterface.class);
recyclerView= findViewById(R.id.recyclerView);
productsAdapter= new ProductsAdapter();
StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(2, LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(staggeredGridLayoutManager);
getData();
}
private void getData() {
dataArrayList = new ArrayList<>();
Map<String, String> params = new HashMap<String, String>();
params.put("categoryId", "0");
params.put("countryId", "1");
Call<List<Product>> call= apiInterfacePages.getProducts(params);
call.enqueue(new Callback<List<Product>>() {
#Override
public void onResponse(Call<List<Product>> call, Response<List<Product>> response) {
dataArrayList = response.body();
productsAdapter.setData(dataArrayList);
recyclerView.setAdapter(productsAdapter);
}
#Override
public void onFailure(Call<List<Product>> call, Throwable t) {
Log.i("Call response",t.getMessage());
}
});
}
}
TestListModel.class
public class TestListModel {
private String testlist_id;
private String test_price;
private String test_name;
private boolean isSelected;
public TestListModel(String testlist_id, String test_price, String test_name,boolean isSelected) {
this.testlist_id = testlist_id;
this.test_price = test_price;
this.test_name = test_name;
this.isSelected = isSelected;
}
public String getTestlist_id() {
return testlist_id;
}
public void setTestlist_id(String testlist_id) {
this.testlist_id = testlist_id;
}
public String getTest_price() {
return test_price;
}
public void setTest_price(String test_price) {
this.test_price = test_price;
}
public String getTest_name() {
return test_name;
}
public void setTest_name(String test_name) {
this.test_name = test_name;
}
public boolean isSelected() {
return isSelected;
}
public void setSelected(boolean isSelected) {
this.isSelected = isSelected;
}
}
JsonResponse.java
public class JSONResponse {
private TestListModel[] result;
public TestListModel[] getResult() {
return result;
}
public void setResult(TestListModel[] result) {
this.result = result;
}
}
HealthActivity.java
public class HealthServicesActivity extends AppCompatActivity implements View.OnClickListener {
/*
*Api call
* */
private RecyclerView recyclerView;
private ArrayList<TestListModel> data;
private RecyclerAdapter madapter;
private Button submitButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_health_services);
ButterKnife.bind(this);
sharePreferenceManager = new SharePreferenceManager<>(getApplicationContext());
submitButton=(Button) findViewById(R.id.submit_button);
showcenterid(sharePreferenceManager.getUserLoginData(LoginModel.class));
initViews();
submitButton.setOnClickListener(this);
/*
* On Click Listner
* */
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.submit_button:
int totalAmount = 0;
int totalPrice = 0;
String testName = "";
String testPrice="";
int count = 0;
List<TestListModel> stList = ((RecyclerAdapter) madapter)
.getTestList();
for (int i = 0; i < stList.size(); i++) {
TestListModel singleStudent = stList.get(i);
//AmountCartModel serialNumber = stList.get(i);
if (singleStudent.isSelected() == true) {
testName = testName + "\n" + singleStudent.getTest_name().toString();
testPrice = testPrice+"\n" + singleStudent.getTest_price().toString();
count++;
totalAmount = Integer.parseInt(stList.get(i).getTest_price());
totalPrice = totalPrice + totalAmount;
}
}
Toast.makeText(HealthServicesActivity.this,
"Selected Lists: \n" + testName+ "" + testPrice, Toast.LENGTH_LONG)
.show();
Intent in= new Intent(HealthServicesActivity.this, AmountCartActivity.class);
in.putExtra("test_name", testName);
in.putExtra("test_price", testPrice);
//in.putExtra("total_price",totalPrice);
in.putExtra("total_price", totalPrice);
in.putExtra("serialNumber", count);
startActivity(in);
finish();
break;
/** back Button Click
* */
case R.id.back_to_add_patient:
startActivity(new Intent(getApplicationContext(), PatientActivity.class));
finish();
break;
default:
break;
}
}
/** show center Id in action bar
* */
#Override
protected void onResume() {
super.onResume();
showcenterid(sharePreferenceManager.getUserLoginData(LoginModel.class));
}
private void showcenterid(LoginModel userLoginData) {
centerId.setText(userLoginData.getResult().getGenCenterId());
centerId.setText(userLoginData.getResult().getGenCenterId().toUpperCase());
deviceModeName.setText(userLoginData.getResult().getDeviceModeName());
}
private void initViews() {
recyclerView = (RecyclerView)findViewById(R.id.test_list_recycler_view);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
loadJSON();
}
private void loadJSON() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(" http://192.168.1.80/aoplnew/api/")
//
.baseUrl("https://earthquake.usgs.gov/fdsnws/event/1/query?")
.addConverterFactory(GsonConverterFactory.create())
.build();
ApiInterface request = retrofit.create(ApiInterface.class);
Call<JSONResponse> call = request.getTestLists();
call.enqueue(new Callback<JSONResponse>() {
#Override
public void onResponse(Call<JSONResponse> call, Response<JSONResponse> response) {
JSONResponse jsonResponse = response.body();
data = new ArrayList<>(Arrays.asList(jsonResponse.getResult()));
madapter = new RecyclerAdapter(data);
recyclerView.setAdapter(madapter);
}
#Override
public void onFailure(Call<JSONResponse> call, Throwable t) {
Log.d("Error",t.getMessage());
}
});
}
HealthRecyclerAdapter.java
public class RecyclerAdapter extends
RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
private ArrayList<TestListModel> android;
public RecyclerAdapter(ArrayList<TestListModel> android) {
this.android = android;
}
#Override
public RecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.test_list_row,parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(RecyclerAdapter.ViewHolder holder, final int position) {
holder.test_name.setText(android.get(position).getTest_name());
holder.test_price.setText(android.get(position).getTest_price());
holder.chkSelected.setChecked(android.get(position).isSelected());
holder.chkSelected.setTag(android.get(position));
holder.chkSelected.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
CheckBox cb = (CheckBox) v;
TestListModel contact = (TestListModel) cb.getTag();
contact.setSelected(cb.isChecked());
android.get(position).setSelected(cb.isChecked());
Toast.makeText(
v.getContext(),
"Clicked on Checkbox: " + cb.getText() + " is " + cb.isChecked(), Toast.LENGTH_LONG).show();
}
});
}
#Override
public int getItemCount() {
return android.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView test_name;
private TextView test_price;
public CheckBox chkSelected;
public TestListModel testLists;
public ViewHolder(View itemView) {
super(itemView);
test_name = (TextView)itemView.findViewById(R.id.test_name);
test_price = (TextView)itemView.findViewById(R.id.price_name);
chkSelected = (CheckBox) itemView.findViewById(R.id.check_box);
}
}
// method to access in activity after updating selection
public List<TestListModel> getTestList() {
return android;
}
AmountCartModel.java
public class AmountCartModel {
private String testName;
private String testPrice;
private Integer serialNumber;
private Integer totalPrice;
public AmountCartModel() {
this.testName = testName;
this.testPrice = testPrice;
this.serialNumber = serialNumber;
this.totalPrice = totalPrice;
}
public String getTestName() {
return testName;
}
public void setTestName(String testName) {
this.testName = testName;
}
public String getTestPrice() {
return testPrice;
}
public void setTestPrice(String testPrice) {
this.testPrice = testPrice;
}
public Integer getSerialNumber() {
return serialNumber;
}
public void setSerialNumber(Integer serialNumber) {
this.serialNumber = serialNumber;
}
public Integer getTotalPrice() {
return totalPrice;
}
public void setTotalPrice(Integer totalPrice) {
this.totalPrice = totalPrice;
}
}
AmountCartActivity.java
public class AmountCartActivity extends AppCompatActivity implements View.OnClickListener {
#BindView(R.id.total_price)
TextView totalPriceDisplay;
SharePreferenceManager<LoginModel> sharePreferenceManager;
private RecyclerView recyclerView;
List<AmountCartModel> mydataList ;
private MyAdapter madapter;
Bundle extras ;
String testName="";
String testPrice="";
String totalPrice= "";
int counting = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_amount_cart);
ButterKnife.bind(this);
sharePreferenceManager = new SharePreferenceManager<>(getApplicationContext());
showcenterid(sharePreferenceManager.getUserLoginData(LoginModel.class));
mydataList = new ArrayList<>();
/*
* Getting Values From BUNDLE
* */
extras = getIntent().getExtras();
if (extras != null) {
testName = extras.getString("test_name");
testPrice = extras.getString("test_price");
totalPrice = String.valueOf(extras.getInt("total_price"));
counting = extras.getInt("serialNumber");
//Just add your data in list
AmountCartModel mydata = new AmountCartModel(); // object of Model Class
mydata.setTestName(testName );
mydata.setTestPrice(testPrice);
mydata.setTotalPrice(Integer.valueOf(totalPrice));
mydata.setSerialNumber(counting);
mydataList.add(mydata);
//totalPriceDisplay.setText(totalPrice);
}
madapter=new MyAdapter(mydataList);
madapter.setMyDataList(mydataList);
recyclerView = (RecyclerView)findViewById(R.id.recyler_amount_cart);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(madapter);
RecyclerAdapter.java //RecyclerAdapter for AmountCart
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>
{
private List<AmountCartModel> context;
private List<AmountCartModel> myDataList;
public MyAdapter(List<AmountCartModel> context) {
this.context = context;
myDataList = new ArrayList<>();
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
// Replace with your layout
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.amount_cart_row, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
// Set Your Data here to yout Layout Components..
// to get Amount
/* myDataList.get(position).getTestName();
myDataList.get(position).getTestPrice();*/
holder.testName.setText(myDataList.get(position).getTestName());
holder.testPrice.setText(myDataList.get(position).getTestPrice());
holder.textView2.setText(myDataList.get(position).getSerialNumber());
}
#Override
public int getItemCount() {
/*if (myDataList.size() != 0) {
// return Size of List if not empty!
return myDataList.size();
}
return 0;*/
return myDataList.size();
}
public void setMyDataList(List<AmountCartModel> myDataList) {
// getting list from Fragment.
this.myDataList = myDataList;
notifyDataSetChanged();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView testName,testPrice,textView2;
public ViewHolder(View itemView) {
super(itemView);
// itemView.findViewById
testName=itemView.findViewById(R.id.test_name_one);
testPrice=itemView.findViewById(R.id.test_price);
textView2=itemView.findViewById(R.id.textView2);
}
}
}
#Override
public void onBackPressed() {
super.onBackPressed();
startActivity(new
Intent(AmountCartActivity.this,HealthServicesActivity.class));
finish();
}
}
This is my code.
Here I am taking HealthActivity and in this class by using recycler view I have displayed testList in recycler view. I am passing testList whichever I am selecting through checkbox to AmountCartActivity of recycler View, And, I am calculating total amount of the selected testList and I am getting the result and that result I am passing to the AmountCart Activity through bundle and I am getting correct result in bundle, but, when I am trying to display total amount in a textView its showing me nothing.
And, my second problem is,
I am trying to display serial number to to my AmountCartActivity of recycler view whichever I am selecting from previous HealthCartActivity using checkbox. And, I have implemented some code but I am not getting how to solve it. please help me.
For Issue#1
Data should be passed onto the Adapter through constructor. The issue could simply be adding another parameter to the constructor:
public MyAdapter(List<AmountCartModel> context, List<AmountCartModel> myDataList) {
this.context = context;
myDataList = this.myDataList;
}
Or,
To add selection support to a RecyclerView instance:
Determine which selection key type to use, then build a ItemKeyProvider.
Implement ItemDetailsLookup: it enables the selection library to access information about RecyclerView items given a MotionEvent.
Update item Views in RecyclerView to reflect that the user has selected or unselected it.
The selection library does not provide a default visual decoration for the selected items. You must provide this when you implement onBindViewHolder() like,
In onBindViewHolder(), call setActivated() (not setSelected()) on the View object with true or false (depending on if the item is selected).
Update the styling of the view to represent the activated status.
For Issue #2
Try using passing data through intents.
The easiest way to do this would be to pass the serial num to the activity in the Intent you're using to start the activity:
Intent intent = new Intent(getBaseContext(), HealthServicesActivity.class);
intent.putExtra("EXTRA_SERIAL_NUM", serialNum);
startActivity(intent);
Access that intent on next activity
String sessionId= getIntent().getStringExtra("EXTRA_SERIAL_NUM");
i am trying implement search function in my section recyclerview
its not working but also not showing error...
i try with edittext addTextChangedListener method.
then in adapter add notifydatachanged method.
try with normal recyclerview its working fine but when use with section recyclerview its not working
sorry for bad english
here is mainActivty
here i get data from server and pass to the adapter in this class i am add the method for filter recyclerview
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_section_rv_search_prac);
init();
initView();
setUpRecyclerView();
tempModels = new ArrayList<TempModel>();
serviceRequest();
searchItem();
}
private void init() {
mAdapter = new ItemRecyclerViewAdapter(SectionRvSearchPrac.this);
}
private void initView() {
mEt_search = findViewById(R.id.et_search_main);
}
///////////////////////////////
private void searchItem() {
mEt_search.addTextChangedListener(
new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
#Override
public void afterTextChanged(Editable s) {
filter(s.toString());
}
});
}
//method for filter list is here..
private void filter(String text) {
ArrayList<TempModel> mFilter_list = new ArrayList<>();
for (TempModel tempModel : tempModels) {
if (tempModel.getName().toLowerCase().contains(text.toLowerCase())) {
mFilter_list.add(tempModel);
}
}
Log.d(TAG, "filter: " + mFilter_list);
mAdapter.filterList(mFilter_list);
}
//////////////////
private void setUpRecyclerView() {
recyclerView = (RecyclerView) findViewById(R.id.sectioned_recycler_view);
recyclerView.setHasFixedSize(true);
linearLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(linearLayoutManager);
}
private void serviceRequest() {
StringRequest stringRequest =
new StringRequest(
Request.Method.GET,
JSON_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
parseJason(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// displaying the error in toast if occurrs
Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_SHORT)
.show();
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
public void parseJason(String response) {
{
Log.d(TAG, "onResponse: " + response);
String[] first;
ArrayList<String> sewction_list = new ArrayList<>();
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("data");
String data = jsonArray.getString(0);
first = data.split(Pattern.quote("***^^^***"));
myList_sec = new ArrayList<>(Arrays.asList(first));
for (int j = 0; j < myList_sec.size(); j++) {
myList_first =
new ArrayList<>(Arrays.asList(myList_sec.get(j).split(Pattern.quote("^^^^"))));
sewction_list.add(myList_first.get(0));
myList_second =
new ArrayList<>(Arrays.asList(myList_first.get(1).split(Pattern.quote("^^"))));
ArrayList<String> id = new ArrayList<>();
ArrayList<String> url = new ArrayList<>();
ArrayList<String> img = new ArrayList<>();
ArrayList<String> name = new ArrayList<>();
for (int i = 0; i < myList_second.size(); i++) {
myList_third =
new ArrayList<>(Arrays.asList(myList_second.get(i).split(Pattern.quote("**"))));
url.add(myList_third.get(0));
img.add(myList_third.get(1));
name.add(myList_third.get(2));
id.add(myList_third.get(3));
tempModels.add(
new TempModel(
myList_third.get(2),
myList_third.get(0),
myList_third.get(1),
myList_third.get(3)));
}
sectionModelArrayList.add(new SectionModel(sewction_list, tempModels));
SectionRecyclerViewAdapter adapter =
new SectionRecyclerViewAdapter(
SectionRvSearchPrac.this, recyclerViewType, sectionModelArrayList);
recyclerView.setAdapter(adapter);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
here is myitemadapter class for child item
public class ItemRecyclerViewAdapter
extends RecyclerView.Adapter<ItemRecyclerViewAdapter.ItemViewHolder> {
private static final String TAG = "adapter";
private Context context;
ArrayList<TempModel> tempModels;
public ItemRecyclerViewAdapter(Context context) {
this.context = context;
}
public void setData(ArrayList<TempModel> data) {
this.tempModels = data;
}
#Override
public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view =
LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_custom_row_layout, parent, false);
return new ItemViewHolder(view);
}
#Override
public void onBindViewHolder(ItemViewHolder holder, final int position) {
String path = tempModels.get(position).getImage();
holder.itemLabel.setText(tempModels.get(position).getName());
Picasso.get().load(path).into(holder.imageView);
holder.cardView.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {}
});
}
#Override
public int getItemCount() {
return tempModels.size();
}
/// here method for update filter list
public void filterList(ArrayList<TempModel> filterdNames) {
this.tempModels = filterdNames;
notifyDataSetChanged();
}
class ItemViewHolder extends RecyclerView.ViewHolder {
private TextView itemLabel;
ImageView imageView;
CardView cardView;
public ItemViewHolder(View itemView) {
super(itemView);
itemLabel = (TextView) itemView.findViewById(R.id.item_label);
cardView = itemView.findViewById(R.id.cardview);
imageView = itemView.findViewById(R.id.img);
}
}
section model for section item
public class SectionModel {
private ArrayList<String> sectionLabel;
private ArrayList<TempModel> tempModels;
public SectionModel(ArrayList<String> sectionLabel, ArrayList<TempModel> tempModels) {
this.sectionLabel = sectionLabel;
this.tempModels = tempModels;
}
public ArrayList<String> getSectionLabel() {
return sectionLabel;
}
public ArrayList<TempModel> getTempModels() {
return tempModels;
}
}
model class for item
public class TempModel implements Parcelable{
String name;
String url;
String image;
String num;
public TempModel() {
}
public TempModel(String name, String url, String image, String num) {
this.name = name;
this.url = url;
this.image = image;
this.num = num;
}
protected TempModel(Parcel in) {
name = in.readString();
url = in.readString();
image = in.readString();
num = in.readString();
}
public static final Creator<TempModel> CREATOR = new Creator<TempModel>() {
#Override
public TempModel createFromParcel(Parcel in) {
return new TempModel(in);
}
#Override
public TempModel[] newArray(int size) {
return new TempModel[size];
}
};
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getNum() {
return num;
}
public void setNum(String num) {
this.num = num;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(url);
dest.writeString(image);
dest.writeString(num);
}
}
sectionadapter class
public class SectionRecyclerViewAdapter
extends RecyclerView.Adapter<SectionRecyclerViewAdapter.SectionViewHolder> {
private static final String TAG = "section";
class SectionViewHolder extends RecyclerView.ViewHolder {
private TextView sectionLabel, showAllButton;
private RecyclerView itemRecyclerView;
public SectionViewHolder(View itemView) {
super(itemView);
sectionLabel = (TextView) itemView.findViewById(R.id.section_label);
itemRecyclerView = (RecyclerView) itemView.findViewById(R.id.item_recycler_view);
}
}
private Context context;
private RecyclerViewType recyclerViewType;
private ArrayList<SectionModel> sectionModelArrayList;
public SectionRecyclerViewAdapter(
Context context,
RecyclerViewType recyclerViewType,
ArrayList<SectionModel> sectionModelArrayList) {
this.context = context;
this.recyclerViewType = recyclerViewType;
this.sectionModelArrayList = sectionModelArrayList;
}
#Override
public SectionViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.rrow, parent, false);
return new SectionViewHolder(view);
}
#Override
public void onBindViewHolder(SectionViewHolder holder, int position) {
final SectionModel sectionModel = sectionModelArrayList.get(position);
holder.sectionLabel.setText(sectionModel.getSectionLabel().get(position));
// recycler view for items
holder.itemRecyclerView.setHasFixedSize(true);
holder.itemRecyclerView.setNestedScrollingEnabled(false);
GridLayoutManager gridLayoutManager = new GridLayoutManager(context, 3);
holder.itemRecyclerView.setLayoutManager(gridLayoutManager);
/* set layout manager on basis of recyclerview enum type */
ItemRecyclerViewAdapter adapter = new ItemRecyclerViewAdapter(context);
adapter.setData(sectionModel.getTempModels());
holder.itemRecyclerView.setAdapter(adapter);
}
#Override
public int getItemCount() {
return sectionModelArrayList.size();
}
Your code very confusing so i just write my solution.
public class SomeAdapter extends RecyclerView.Adapter<SomeAdapter.SomeViewHolder> implements Filterable{
...
#Override
public Filter getFilter() {
Filter filter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
mMainList = mYourJSONResponseList;
FilterResults results = new FilterResults();
ArrayList<YourModel> mFilter_list = new ArrayList<>();
//Place your logic
for (YourModel model : mMainList) {
if(model.getName().
toLowerCase().contains(text.toLowerCase())) {
mFilter_list.add(model);
}
}
results.count = mFilter_list.size();
results.values = mFilter_list;
return results;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
mMainList = (ArrayList<YourModel>) filterResults.values;
notifyDataSetChanged();
}
};
return filter;
}
And add this into your text listener
#Override
public void afterTextChanged(Editable s) {
//Add this
adapter.getFilter().filter(s.toString())
}
NOTE!! You will show mMainList only this list in your RecyclerView, And check nullpointerexceptions
im using thoughtbot expandable recyclerview (https://github.com/thoughtbot/expandable-recycler-view) and i can't get to expand groups on clicks. also i know that the child items are not even binded (not sure if they were supposed to bind or only on expanding of group.)
my view holders:
public class PlaylistViewHolder extends GroupViewHolder {
private TextView mPlaylistName, mPlaylistCount;
private ImageView arrow;
ExpandableListView.OnGroupClickListener listener;
public PlaylistViewHolder(View itemView) {
super(itemView);
mPlaylistName = itemView.findViewById(R.id.playlistNameView);
mPlaylistCount = itemView.findViewById(R.id.videosCount);
arrow = itemView.findViewById(R.id.expandBtn);
}
public void setCurrentPlaylist(YoutubePlaylist playlist){
Log.e("###",playlist.toString());
mPlaylistName.setText(playlist.getListTitle());
mPlaylistCount.setText("5");
}
}
/////
public class VideoViewHolder extends ChildViewHolder {
TextView mVideoName,mVideoLinkView;
ImageView mVideoThumb;
public VideoViewHolder(View itemView) {
super(itemView);
mVideoName = itemView.findViewById(R.id.videoNameView);
mVideoThumb = itemView.findViewById(R.id.videoThumb);
mVideoLinkView = itemView.findViewById(R.id.videoLinkView);
}
public void onBind(YoutubeVideo video){
Log.e("###","Video binded!!!!!!!");
mVideoName.setText(video.getTitle());
mVideoLinkView.setText(video.getThumbnailLink());
}
}
my classes:
the group class:
public class YoutubePlaylist extends ExpandableGroup<YoutubeVideo> {
#SerializedName("ListTitle")
private String title;
#SerializedName("ListItems")
private ArrayList<YoutubeVideo> videos;
public YoutubePlaylist(String title, List<YoutubeVideo> items) {
super(title, items);
this.title = title;
}
public String getListTitle() {
return title;
}
public void setListTitle(String listTitle) {
this.title = listTitle;
}
public ArrayList<YoutubeVideo> getVideos() {
return videos;
}
public void setVideos(ArrayList<YoutubeVideo> videos) {
this.videos = videos;
}
#Override
public String toString() {
return "YoutubePlaylist{" +
"title='" + title + '\'' +
", videos=" + videos +
'}';
}
}
my child class:
class YoutubeVideo implements Parcelable {
#SerializedName("Title")
private String title;
#SerializedName("link")
private String linkToVideo;
#SerializedName("thumb")
private String thumbnailLink;
public YoutubeVideo(String title, String linkToVideo, String thumbnailLink) {
this.title = title;
this.linkToVideo = linkToVideo;
this.thumbnailLink = thumbnailLink;
}
protected YoutubeVideo(Parcel in) {
title = in.readString();
linkToVideo = in.readString();
thumbnailLink = in.readString();
}
public static final Creator<YoutubeVideo> CREATOR = new Creator<YoutubeVideo>() {
#Override
public YoutubeVideo createFromParcel(Parcel in) {
return new YoutubeVideo(in);
}
#Override
public YoutubeVideo[] newArray(int size) {
return new YoutubeVideo[size];
}
};
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getLinkToVideo() {
String newLink;
if (linkToVideo.contains(" ")) {
newLink = linkToVideo.replaceAll(" ", "");
return newLink;
}
return linkToVideo;
}
public void setLinkToVideo(String linkToVideo) {
this.linkToVideo = linkToVideo;
}
public String getThumbnailLink() {
String fixedThumb=thumbnailLink;
if (thumbnailLink.contains(" ")) {
fixedThumb = thumbnailLink.replaceAll(" ", "");
return fixedThumb;
}
return thumbnailLink;
}
public void setThumbnailLink(String thumbnailLink) {
this.thumbnailLink = thumbnailLink;
}
#Override
public String toString() {
return "YoutubeVideo{" +
"title='" + getTitle() + '\'' +
", linkToVideo='" + getLinkToVideo() + '\'' +
", thumbnailLink='" + getThumbnailLink() + '\'' +
'}';
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(title);
dest.writeString(linkToVideo);
dest.writeString(thumbnailLink);
}
}
the adapter:
public class PlaylistAdapter extends
ExpandableRecyclerViewAdapter<PlaylistViewHolder, VideoViewHolder> {
public PlaylistAdapter(List<? extends ExpandableGroup> groups) {
super(groups);
}
#Override
public PlaylistViewHolder onCreateGroupViewHolder(ViewGroup parent, int
viewType) {
View view =
LayoutInflater.from(parent.getContext()).inflate(R.layout.playlist_item,
parent, false);
return new PlaylistViewHolder(view);
}
#Override
public VideoViewHolder onCreateChildViewHolder(ViewGroup parent, int
viewType) {
View view =
LayoutInflater.from(parent.getContext()).inflate(R.layout.video_item,
parent,
false);
return new VideoViewHolder(view);
}
#Override
public void onBindChildViewHolder(VideoViewHolder holder, int flatPosition,
ExpandableGroup group, int childIndex) {
YoutubeVideo video = (YoutubeVideo) group.getItems().get(childIndex);
holder.onBind(video);
}
#Override
public void onBindGroupViewHolder(PlaylistViewHolder holder, int
flatPosition, ExpandableGroup group) {
holder.setCurrentPlaylist((YoutubePlaylist) group);
}
}
main activity:
public class MainActivity extends AppCompatActivity {
RecyclerView videoListView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GetJsonFromUrl getJsonService = RetrofitInstance.getRetrofitInstance().create(GetJsonFromUrl.class);
Call<JsonObject> call = getJsonService.getJSON();
call.enqueue(new Callback<JsonObject>() {
#Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
if(response.isSuccessful()){
JsonArray array = response.body().getAsJsonArray("Playlists");
Gson gson = new Gson();
Type type = new TypeToken<ArrayList<YoutubePlaylist>>(){}.getType();
ArrayList<YoutubePlaylist> youtubePlay = gson.fromJson(array, type);
for(YoutubePlaylist playlist : youtubePlay){
ArrayList<YoutubeVideo> videos = playlist.getVideos();
Log.e("###",videos.toString());
}
setArrayToAdapter(youtubePlay);
}
}
#Override
public void onFailure(Call<JsonObject> call, Throwable t) {
}
});
}
private void setArrayToAdapter(ArrayList<YoutubePlaylist> youtubePlay) {
videoListView = findViewById(R.id.videosView);
LinearLayoutManager manager = new LinearLayoutManager(this);
PlaylistAdapter adapter = new PlaylistAdapter(youtubePlay);
videoListView.setLayoutManager(manager);
videoListView.setAdapter(adapter);
}
}
playlist object output example:
YoutubePlaylist{title='Zen Work Music', videos=[YoutubeVideo{title='HEALING ZEN Music', linkToVideo='https://www.youtube.com/watch?v=SbCpzWMWb68', thumbnailLink='https://i.ytimg.com/vi_webp/SbCpzWMWb68/mqdefault.webp'}, YoutubeVideo{title='Relaxing Music - Meditation', linkToVideo='https://www.youtube.com/watch?v=qrx1vyvtRLY', thumbnailLink='https://i.ytimg.com/vi_webp/qrx1vyvtRLY/mqdefault.webp'}, YoutubeVideo{title='Relaxing Music - Background', linkToVideo='https://www.youtube.com/watch?v=loIZy6GqhUw', thumbnailLink='https://i.ytimg.com/vi_webp/loIZy6GqhUw/mqdefault.webp'}, YoutubeVideo{title='Delta Waves Sleep Music', linkToVideo='https://www.youtube.com/watch?v=EshmcHB3yMg', thumbnailLink='https://i.ytimg.com/vi_webp/EshmcHB3yMg/mqdefault.webp'}]}
im getting the groups binded and shown on list, but nothing happens onClick and i did'nt see anything regarding onClickListener in the documentation.
Thanks in advance!
The issue with this is that from the documentation here you don't have to pass your custom model YoutubePlaylist.java as a parameter as you did rather you replace it with ExpandableGroup so for your code
public class PlaylistViewHolder extends GroupViewHolder {
private TextView mPlaylistName, mPlaylistCount;
private ImageView arrow;
ExpandableListView.OnGroupClickListener listener;
public PlaylistViewHolder(View itemView) {
super(itemView);
mPlaylistName = itemView.findViewById(R.id.playlistNameView);
mPlaylistCount = itemView.findViewById(R.id.videosCount);
arrow = itemView.findViewById(R.id.expandBtn);
}
public void setCurrentPlaylist(ExpandableGroup playlist){
//the parameter has to be ExpandableGroup class and you can only get title
Log.e("###",playlist.getTitle());//you must call the getTitle() method
mPlaylistName.setText(playlist.getListTitle());
mPlaylistCount.setText("5");
}
}
This could be the way it was built. maybe a workaround this may be for
this method to then accept two parameters which is the ExpandableGroup
class and the custom model, class
public void setCurrentPlaylist(ExpandableGroup playlist, YoutubePlaylist playlist2){
//the parameter has to be ExpandableGroup class and you can only get title
Log.e("###",playlist.getTitle());//you must call the getTitle() method
mPlaylistName.setText(playlist2.getListTitle());
mPlaylistCount.setText("5");
}