I have a Recycler View and I want my webView to display different website when different items on the Recycler View is clicked.
I have implemented a recycler view which has An ImageView, and two text views. I want a website to be opened in the webview anytime an item on the recycler view is clicked. I want different websites to be opened anytime an item from different rows on the recycler view is clicked.
I have tried different methods but its still not working.
These are my codes
RecyclerViewAdapter:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>{
private static final String TAG = "RecyclerViewAdapter";
private ArrayList<String> mImageViews = new ArrayList<>();
private ArrayList<String> mBlogDescriptions = new ArrayList<>();
public ArrayList<String> mBlogNames = new ArrayList<>();
private Context mContext;
public RecyclerViewAdapter mViewAdapter;
public RecyclerViewAdapter(ArrayList<String> imageViews, ArrayList<String> blogDescriptions,ArrayList<String> blogNames, Context context) {
mImageViews = imageViews;
mBlogDescriptions = blogDescriptions;
mBlogNames = blogNames;
mContext = context;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_list_item, parent, false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder holder, final int position) {
Log.d(TAG, "onBindViewHolder: called.");
String currentItem = mBlogNames.get(position);
Glide.with(mContext)
.asBitmap()
.load(mImageViews.get(position))
.into(holder.mImageView);
holder.mBlogDescription.setText(mBlogDescriptions.get(position));
holder.mBlogName.setText(mBlogNames.get(position));
holder.mBlogName.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Bundle extras = new Bundle();
extras.putStringArray("url", new String[]{"www.goal.com","www.facebook.com","www.twitter.com","www.youtube.com"});
extras.get(String.valueOf(position));
Intent intent = new Intent(mContext,WebViewActivity.class);
intent.putExtras(extras);
}
});
}
#Override
public int getItemCount() {
return mBlogDescriptions.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
CircleImageView mImageView;
TextView mBlogDescription;
TextView mBlogName;
RelativeLayout mRelativeLayout;
public ViewHolder(#NonNull View itemView) {
super(itemView);
mImageView =itemView.findViewById(R.id.circular_image);
mBlogDescription = itemView.findViewById(R.id.blog_description);
mBlogName = itemView.findViewById(R.id.blog_name);
mRelativeLayout = itemView.findViewById(R.id.parent_layout);
}
}
}
WebViewActivity
public class WebViewActivity extends AppCompatActivity {
private WebView mWebView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_web_view);
mWebView = findViewById(R.id.web_view);
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
mWebView.setWebViewClient(new WebViewClient());
Bundle extras = this.getIntent().getExtras();
String[] array = extras.getStringArray("url");
mWebView.loadUrl("array");
}
#Override
public void onBackPressed() {
if (mWebView.canGoBack()) {
mWebView.goBack();
} else {
super.onBackPressed();
}
}
}
please help me with a solution.
Thanks
From my understanding you are trying to create different webviews in your recycler view.
If that is the case i would suggest
creating an android resource file containing the webview
creating an array with the different urls you would like to see in the webview.
Creating a recyclerview adapter that inflates the recource file with the data inside your array.
Pass the adapter into the recycler view.
If you have the urls set with the views inside your recyclerview. What you need to do is
You should implement onTouchEventLister to your recycler view
Then get the view that was touched by getting the view in the position of the touch.
Get the data from that view e.g. if the view that was touched was a textview with text as url. You can get the text from it.
Update the webview url with the url you got from the textview.
Since the two views are on the same context, you can call them from within the ontoucheventlistener
I hope this answers your question.
implementation 'androidx.browser:browser:1.0.0'
CustomTabsIntent.Builder intentBuilder = new CustomTabsIntent.Builder();
intentBuilder.setToolbarColor(getColor(context, R.color.colorPrimary));
intentBuilder.setSecondaryToolbarColor(getColor(context, R.color.colorPrimaryDark));
intentBuilder.build().launchUrl(context, Uri.parse(url));
I hope this will help you:)
Related
I have created android app like gallery which have some images using gridview fragment.
Functionality of my application is working fine and image showing in fragment gridview and also my second activity open when i click on item but i want to show cardview GridView with Animations.
Also if it is easier default image in place of loading images instead of progress bar will be fine.
Here is my application fragment code :
public class CallFragment extends Fragment {
GridView grid;
String[] plan = {
"Student Bundle",
"SMS Plus Bundle",
"Instagram",
"Facebook",
"Flickr"
} ;
String[] web = {
"*3000",
"*106*1",
"Instagram",
"Facebook",
"Flickr"
} ;
int[] imageId = {
R.drawable.calla,
R.drawable.smsb,
R.drawable.person7,
R.drawable.person7,
R.drawable.person7
};
int[] fullimg = {
R.drawable.callaa,
R.drawable.smsbb,
R.drawable.person7,
R.drawable.person7,
R.drawable.person7
};
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setHasOptionsMenu(true);
View view = inflater.inflate(R.layout.fragment_call,container,false);
CustomGrid adapter = new CustomGrid(getActivity(), plan, web, imageId, fullimg);
grid=(GridView) view.findViewById(R.id.grid);
grid.setAdapter(adapter);
grid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String value=(String)grid.getItemAtPosition(i);
Intent intent=new Intent(getActivity(),Book.class);
intent.putExtra("web", web[i]);
intent.putExtra("plan", plan[i]);
intent.putExtra("imageId", imageId[i]);
intent.putExtra("fullimg", fullimg[i]);
startActivity(intent);
}
});
return view;
}
Here is my application CustomAdapter code :
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.MyViewHolder> {
ArrayList<String> personNames;
ArrayList<String> personCode;
ArrayList<Integer> personImages;
ArrayList<Integer> personImages1;
Context context;
public CustomAdapter(Context context, ArrayList<String> personNames, ArrayList<String> personCode, ArrayList<Integer> personImages, ArrayList<Integer> personImages1) {
this.context = context;
this.personCode = personCode;
this.personNames = personNames;
this.personImages = personImages;
this.personImages1 = personImages1;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// infalte the item Layout
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.rowlayout, parent, false);
// set the view's size, margins, paddings and layout parameters
MyViewHolder vh = new MyViewHolder(v); // pass the view to View Holder
return vh;
}
#Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
// set the data in items
//holder.name.setText(personNames.get(position));
holder.image.setImageResource(personImages.get(position));
//holder.image.setImageResource(personImages1.get(position));
// implement setOnClickListener event on item view.
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// open another activity on item click
Intent intent = new Intent(context, SecondActivity.class);
//intent.putExtra("image", personImages.get(position)); // put image data in Intent
intent.putExtra("name", personNames.get(position)); // put image data in Intent
intent.putExtra("code", personCode.get(position)); // put image data in Intent
intent.putExtra("image", personImages1.get(position)); // put image data in Intent
context.startActivity(intent); // start Intent
}
});
}
#Override
public int getItemCount() {
return personNames.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
// init the item view's
TextView name;
TextView code;
ImageView image;
public MyViewHolder(View itemView) {
super(itemView);
// get the reference of item view's
name = (TextView) itemView.findViewById(R.id.name);
code = (TextView) itemView.findViewById(R.id.code);
image = (ImageView) itemView.findViewById(R.id.image);
}
}
}
Here is example of my requirement :
My gridview looks like this :
Create an separate XML file under anim and apply in the onBindViewHolder.
#Override
public void onBindViewHolder(ViewHolder holder, int position)
{
// Here you apply the animation when the view is bound
setAnimation(holder.itemView, position);
}
/**
* Here is the key method to apply the animation
*/
private void setAnimation(View viewToAnimate, int position)
{. int lastPosition=0;
// If the bound view wasn't previously displayed on screen, it's animated
if (position > lastPosition)
{
Animation animation = AnimationUtils.loadAnimation(context, android.R.anim.slide_in_left);
viewToAnimate.startAnimation(animation);
lastPosition = position;
}
}
}
You can apply animations on RecyclerView using this tutorial.
and for default image just put a src property inside your imageview in R.layout.rowlayout XML file
Used this Recyclerview with Load animation
Recyclerview Load Animation
I have created android app like gallery which have some images using gridview fragment.
Functionality of my application is working fine and image showing in fragment gridview and also my second activity open when i click on item but i want to show loading image with progress bar when my image not load or take time for loading complete.
Also i want to show image counting number in gridview.
But i want to progress bar on loading images like this : WANT LINK THIS SCREENSHOT
My gridview looks like this : My gridview looks like this
already to find the
Here is my application fragment code :
public class CallFragment extends Fragment {
GridView grid;
String[] plan = {
"Student Bundle",
"SMS Plus Bundle",
"Instagram",
"Facebook",
"Flickr"
} ;
String[] web = {
"*3000",
"*106*1",
"Instagram",
"Facebook",
"Flickr"
} ;
int[] imageId = {
R.drawable.calla,
R.drawable.smsb,
R.drawable.person7,
R.drawable.person7,
R.drawable.person7
};
int[] fullimg = {
R.drawable.callaa,
R.drawable.smsbb,
R.drawable.person7,
R.drawable.person7,
R.drawable.person7
};
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setHasOptionsMenu(true);
View view = inflater.inflate(R.layout.fragment_call,container,false);
CustomGrid adapter = new CustomGrid(getActivity(), plan, web, imageId, fullimg);
grid=(GridView) view.findViewById(R.id.grid);
grid.setAdapter(adapter);
grid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String value=(String)grid.getItemAtPosition(i);
Intent intent=new Intent(getActivity(),Book.class);
intent.putExtra("web", web[i]);
intent.putExtra("plan", plan[i]);
intent.putExtra("imageId", imageId[i]);
intent.putExtra("fullimg", fullimg[i]);
startActivity(intent);
}
});
return view;
}
Here is my application CustomAdapter code :
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.MyViewHolder> {
ArrayList<String> personNames;
ArrayList<String> personCode;
ArrayList<Integer> personImages;
ArrayList<Integer> personImages1;
Context context;
public CustomAdapter(Context context, ArrayList<String> personNames, ArrayList<String> personCode, ArrayList<Integer> personImages, ArrayList<Integer> personImages1) {
this.context = context;
this.personCode = personCode;
this.personNames = personNames;
this.personImages = personImages;
this.personImages1 = personImages1;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// infalte the item Layout
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.rowlayout, parent, false);
// set the view's size, margins, paddings and layout parameters
MyViewHolder vh = new MyViewHolder(v); // pass the view to View Holder
return vh;
}
#Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
// set the data in items
//holder.name.setText(personNames.get(position));
holder.image.setImageResource(personImages.get(position));
//holder.image.setImageResource(personImages1.get(position));
// implement setOnClickListener event on item view.
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// open another activity on item click
Intent intent = new Intent(context, SecondActivity.class);
//intent.putExtra("image", personImages.get(position)); // put image data in Intent
intent.putExtra("name", personNames.get(position)); // put image data in Intent
intent.putExtra("code", personCode.get(position)); // put image data in Intent
intent.putExtra("image", personImages1.get(position)); // put image data in Intent
context.startActivity(intent); // start Intent
}
});
}
#Override
public int getItemCount() {
return personNames.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
// init the item view's
TextView name;
TextView code;
ImageView image;
public MyViewHolder(View itemView) {
super(itemView);
// get the reference of item view's
name = (TextView) itemView.findViewById(R.id.name);
code = (TextView) itemView.findViewById(R.id.code);
image = (ImageView) itemView.findViewById(R.id.image);
}
}
}
Also if it is easier default image in place of loading images instead of progress bar will be fine.
Please provide me solution to implement this.
i hope you get my main point which i want and Thanks for help.
I am creating an AlertDialog custom class, called ActionDialog, which will contains a RecyclerView containing Buttons. I have a List of Button that I populate in the custom class ActionDialog (for now i just populate with useless Button just to try to use it, except one which I create in another class).
The problem is that when i create the AlertDialog, all buttons are showing empty, they are showed but with no text/no clicklistener (as you can see in the image below).
(I have added a custom ActionListener to a Button in another class and then give it as parameter in ActionDialog class. Will it lose the ActionListener?)
Here is the result.
I will leave here my ActionDialog class code, and the adapter class.
This is ActionDialog class:
public class ActionDialog extends AlertDialog{
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
private Button actionButtons;
private List<Button> buttons;
private Activity context;
public ActionDialog(#NonNull Activity context, Button actionButtons) {
super(context);
this.context = context;
this.actionButtons = actionButtons;
buttons = new ArrayList<>();
initButton();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//requestWindowFeature(Window.FEATURE_NO_TITLE);
}
private void initButton(){
initZoneButton();
//TODO init all buttons
Button b1 = new Button(context);
b1.setText("ExampleButton1");
Button b2 = new Button(context);
b2.setText("ExampleButton2");
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String a;
}
});
buttons.add(b1);
buttons.add(b2);
}
private void initZoneButton(){
buttons.add(actionButtons); //this button is created in another class and give as parameter in this class
}
public void createDialog(){
Builder mBuilder = new Builder(context);
View view = context.getLayoutInflater().inflate(R.layout.dialog_actionbuttons_layout, null);
mRecyclerView = view.findViewById(R.id.dialog_actionbuttons_rv);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(context);
mRecyclerView.setLayoutManager(mLayoutManager);
mAdapter = new ActionButtonsAdapter(buttons);
mRecyclerView.setAdapter(mAdapter);
mBuilder.setView(view);
mBuilder.create().show();
}
}
Here is the RecyclerView adapter class:
public class ActionButtonsAdapter extends RecyclerView.Adapter<ActionButtonsAdapter.ViewHolder>{
private List<Button> dataButtons;
static class ViewHolder extends RecyclerView.ViewHolder {
Button actionButton;
ViewHolder(View v) {
super(v);
actionButton = v.findViewById(R.id.action_button_rv);
}
}
public ActionButtonsAdapter(List<Button> dataButtons){
this.dataButtons = dataButtons;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.actionButton = dataButtons.get(position);
//i think the problem is here, maybe
}
#Override
public ActionButtonsAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_actionbutton_layout, parent, false);
return new ViewHolder(v);
}
#Override
public int getItemCount() {
return dataButtons.size();
}
}
I think in the onBindViewHolder method you should do what ever you want to do with your button.
Also there is no need for the list of buttons here. Make a list the data you need to be held in the Buttons RecyclerView.
I have a RecyclerView that will display Genres for restaurants lets say, So I will create a List of strings to hold these genres names (chickens, meats, etc,..)
Setting its text
holder.actionButton.setText(// Make use of position here);
Or Click Listeners.
Update
You can check google samples for recyclerview here
#Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
Log.d(TAG, "Element " + position + " set.");
// Get element from your dataset at this position and replace the contents of the view
// with that element
viewHolder.getTextView().setText(mDataSet[position]);
}
wheres mDataset is Array of Strings.
I've got A Fragment which contains a Layout header with an exit button, a title text and an edit text which is clickable.
Below the header layout I have a RecyclerView that matches the parent layout in width and height.
Each row of the RecyclerView has an ImageView, a title text, a description text, a price text and an invisible ImageView used to remove the item from the Recycler.
Because my EDIT TextView is declared in the Fragment I can't get the ViewHolder inside the adapter in order to change the ImageView visibility like this:
All I want is to make the image visible for each row when the EDIT text is pressed.
Here is the Adapter and ViewHolder code:
public class BagItemsAdapter extends RecyclerView.Adapter<BagItemsAdapter.BagViewHolder> {
private List<BagItem> mBagList;
private Context mContext;
private String quantityPrefix, pricePrefix;
public BagItemsAdapter(Context context,List<BagItem> list)
{
this.mBagList = list;
this.mContext = context;
}
#Override
public BagViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.bag_shop_item_layout,parent,false);
return new BagViewHolder(v);
}
#Override
public void onBindViewHolder(BagViewHolder holder, int position) {
BagItem currentItem = mBagList.get(position);
Picasso.with(mContext).load(currentItem.getItemImageUrl()).into(holder.bagItemImage);
holder.bagItemTitleBrand.setText(currentItem.getItemBrandTitle());
holder.bagItemDescription.setText(currentItem.getItemDescription());
holder.removeBagItem.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
}
#Override
public int getItemCount() {
return mBagList.size();
}
class BagViewHolder extends RecyclerView.ViewHolder{
#BindView(R.id.bag_item_image) ImageView bagItemImage;
#BindView(R.id.remove_bag_item) ImageView removeBagItem;
#BindView(R.id.bag_item_title_brand) TextView bagItemTitleBrand;
#BindView(R.id.bag_item_description) TextView bagItemDescription;
#BindView(R.id.bag_item_quantity) TextView bagItemQuantity;
#BindView(R.id.bag_item_price) TextView bagItemPrice;
#BindView(R.id.bag_item_product) TextView bagItemProduct;
public BagViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this,itemView);
}
}
}
The Fragment code:
public class BagFragment extends Fragment implements BagView {
#BindView(R.id.bag_items_recycler)RecyclerView mRecycler;
#BindView(R.id.edit_bag_items_text)TextView editBagItems;
#BindView(R.id.exit_bag_image)ImageView exitBagImage;
#BindView(R.id.no_items_in_bag_image)ImageView noItemsImage;
#BindView(R.id.no_items_in_bag_text)TextView noItemsText;
#BindView(R.id.my_bag_title_text)TextView myBagTitleText;
#BindView(R.id.check_out_button)Button checkOutButton;
BagPresenter mPresenter;
ItemTouchHelper itemTouchHelper;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPresenter = new BagPresenter(getActivity(),this);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.shopping_bag_fragment_layout,container,false);
ButterKnife.bind(this,v);
mPresenter.getBagItems();
return v;
}
#OnClick({R.id.exit_bag_image,R.id.edit_bag_items_text,R.id.check_out_button})
public void onBagViewsClicked(View v)
{
switch (v.getId())
{
case R.id.exit_bag_image:
getActivity().getSupportFragmentManager().popBackStack();
break;
case R.id.edit_bag_items_text:
if(editBagItems.getText().equals(getActivity().getResources().getString(R.string.edit_string)))
{
editBagItems.setText(getActivity().getResources().getString(R.string.done_string));
editBagItems.setTypeface(Typeface.DEFAULT_BOLD);
//TODO here is where I should make the delete ImageView visible for each item
((BagItemsAdapter)mRecycler.getAdapter()).showDeleteImage(); "this does not work because i can't get the ViewHolder from the adapter"
}else if(editBagItems.getText().equals(getActivity().getResources().getString(R.string.done_string)))
{
editBagItems.setText(getActivity().getResources().getString(R.string.edit_string));
editBagItems.setTypeface(Typeface.DEFAULT);
//TODO here is where I should hide the delete ImageView
((BagItemsAdapter)mRecycler.getAdapter()).hideDeleteImage(); "this does not work"
}
}
}
}
Any help is highly appreciated! :)
First you need to add a new property to your BagItem. We'll called it editMode.
class BagItem {
boolean editMode;
}
Initially editMode is false. When the user push edit button, you need to change editMode to true. Make sure that your mBagList is set to public. Next you need to notify the recycler view adapter that the data was changed.
for (BagItem bagItem: bagItemsAdapter.mBagList) {
bagItem.editMode = true;
}
bagItemsAdapter.notifyDataSetChanged();
You also need to update the visibility of removeBagItem according to editMode value.
holder.removeBagItem.setVisibility(currentItem.editMode ? View.VISIBLE : View.GONE);
first you make one boolean global variable in adapter class for example.
private boolean isVisible = false;
According to that variable set visibility of imageview in onBindViewHolder say for example
if(isVisible){
holder.removeBagItem.setVisibility(View.VISIBLE);
}else{
holder.removeBagItem.setVisibility(View.GONE);
}
Create on public method which set visibility of imageView in adapter for example
public void setVisibility(){
isVisible = true;
this.notifyDataSetChanged();
}
from fragment edit text click call that adapter method for example.
adapter.setVisibility();
I am developing an android application where i am using a RecyclerView to display a list of items.I am getting the list from server as json.So my problem is within this list i am getting another list as item.That is if my main arraylist contain title and materials, the material is another arraylist.So can you please suggest a solution to display a list within recyclerview.
The code below is my adapter
public class CurriculumAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context mContext;
private ArrayList<Curriculum> mArrayListCurriculum;
public CurriculumAdapter(Context mContext, ArrayList<Curriculum> mArrayListCurriculum) {
this.mContext = mContext;
this.mArrayListCurriculum = mArrayListCurriculum;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_key_features, parent,false);
return new KeyFeatureViewHolder(v);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof KeyFeatureViewHolder) {
((KeyFeatureViewHolder) holder).mTextViewFeatureTitle.setText(mArrayListCurriculum.get(position).getTitle());
}
}
#Override
public int getItemCount() {
return mArrayListCurriculum == null ? 0 : mArrayListCurriculum.size();
}
public static class KeyFeatureViewHolder extends RecyclerView.ViewHolder {
public TextView mTextViewFeatureTitle;
public KeyFeatureViewHolder(View itemView) {
super(itemView);
mTextViewFeatureTitle = (TextView) itemView.findViewById(R.id.txtFeature);
}
}
}
The code below is my fragment with dummy arraylist data
public class CourseCurriculumFragment extends Fragment {
private FragmentInterface mFragmentInterface;
private ArrayList<Curriculum> mArrayListCurriculum;
private ArrayList<Material> mArrayListMaterial;
private RecyclerView mRecyclerViewCurriculum;
private LinearLayoutManager mLinearLayoutManager;
private CurriculumAdapter mCurriculumAdapter;
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_course_curriculum, container, false);
return view;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
initView(view);
}
private void initView(View view) {
mArrayListMaterial = new ArrayList<>();
mArrayListCurriculum = new ArrayList<>();
populateMaterials();
populateKeyFeatures();
mRecyclerViewCurriculum = (RecyclerView) view.findViewById(R.id.recyclerViewCurriculum);
mCurriculumAdapter = new CurriculumAdapter(getActivity(), mArrayListCurriculum);
mLinearLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerViewCurriculum.setLayoutManager(mLinearLayoutManager);
mRecyclerViewCurriculum.setAdapter(mCurriculumAdapter);
mRecyclerViewCurriculum.setItemAnimator(new DefaultItemAnimator());
}
private void populateMaterials() {
mArrayListMaterial.add(new Material("12:00","pdf","","Sample Text","0"));
mArrayListMaterial.add(new Material("12:00","pdf","","Sample Text","0"));
}
private void populateKeyFeatures() {
mArrayListCurriculum.add(new Curriculum("UNIT 1",mArrayListMaterial));
mArrayListCurriculum.add(new Curriculum("UNIT 2",mArrayListMaterial));
mArrayListCurriculum.add(new Curriculum("UNIT 3",mArrayListMaterial));
}
}
A bind method in a holder is a good way to pass data to it.
In your case this bind method should take in a Curriculum and a Material object as parameters.
Inside the onBindViewHolder method of the adapter, instead of reaching into the variables of the holder, you should call this bind method.
In the implementation of the method inside the you KeyFeatureViewHolder class you should use these passed parameters and display them in the appropriate UI elements.
Lastly, to get the Material object data into adapter, add ArrayList<Material> as a constructor parameter just like you did with Curriculum.
Use RecyclerView with header, title as header and materials as items of that header. Look at this example.
You need to design a custom list for yourself. For example take an object like this.
public class ListItem {
public curriculumName = null;
public materialName = null;
}
Now populate this list after you parse the JSON string. Get your first Curriculum and populate the object like this
private ArrayList<ListItem> mListItemArray = new ArrayList<ListItem> ();
for(curriculum : mArrayListCurriculum) {
ListItem mListItemHead = new ListItem();
mListItemHead.curriculumName = curriculum.getName();
// Set the header here
mListItemArray.add(mListItemHead);
for(material : curriculum.getMaterials()){
ListItem mListItem = new ListItem();
mListItem.materialName = material.getName();
// Add materials here
mListItemArray.add(mListItem);
}
}
Now, you've a list with headers and materials. When the materialName in your mListItemArray is null, it identifies that this is a header and vice versa.
Now the trick is to modify your adapter of your RecyclerView so that you can bind proper view to your items in your list.
You can find an indication from this answer on how you can achieve this desired behaviour.
Basically, the idea is to modify your getItemViewType to pass the proper view in your onBindViewHolder. Your getItemViewType might look like this.
#Override
public int getItemViewType(int position) {
if (mListItemArray.get(position).curriculumName != null) {
// This is where we'll add header.
return HEADER_VIEW;
}
return super.getItemViewType(position);
}