I have an activity that uses a ViewPager to contain 2 Fragments. Inside one of the fragments I have a recyclerView. Until now When I first run the app the view is show correctly. The fragment makes a request to a web service and loads the data into the fragment's recyclerview and all good. Now my problem is that I must filter the data loaded into the recycler view from the MainActivity by just passing an Integer number but the recyclerview is not updating.
This is my code:
how I set my viewPager in MainActivity:
setSupportActionBar(toolbar);
ViewPagerAdapter adapterpager = new ViewPagerAdapter(getSupportFragmentManager(),context);
viewPager.setAdapter(adapterpager);
tabLayout.setupWithViewPager(viewPager);
ViewPagerAdapter:
public class ViewPagerAdapter extends FragmentPagerAdapter {
Context context;
public ViewPagerAdapter(FragmentManager fm, Context context) {
super(fm);
this.context=context;
}
#Override
public Fragment getItem(int position) {
ActivitiesFragment activitiesFragment = new ActivitiesFragment(context);
ArticlesFragment articlesFragment = new ArticlesFragment(context);
Fragment fragment = new Fragment();
if (position==0) {
fragment = activitiesFragment;
}else if (position==1){
fragment = articlesFragment;
}
return fragment;
}
#Override
public int getCount() {
return 2;
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
position = position+1;
String tabTittle="Activities";
if (position==2){
tabTittle = "Articles";
}
return tabTittle;
}
}
My ActivitiesFragment:
public class ActivitiesFragment extends Fragment implements ActivitiesResponse {
private RecyclerView activityRecycler;
private RequestMethods req;
private String skillId="1";
private String babyId="50";
Context context;
private ActivitiesRecyclerAdapter activitiesRecyclerAdapter;
public ActivitiesFragment(Context context) {
// Required empty public constructor
this.context=context;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_activities, container, false);
activityRecycler = v.findViewById(R.id.activities_recycler);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context);
linearLayoutManager.setOrientation(RecyclerView.VERTICAL);
activityRecycler.setLayoutManager(linearLayoutManager);
req = new RequestMethods(context);
req.getActivities(skillId,babyId,0);
req.onActivityResponse(this);
return v;
}
#Override
public void getActivities(List<Activity> list, int age) {
List<Activity> activityList = new ArrayList<>();
int listPos=0;
if (age==0){
activityList = list;
}else{
for (int x =0;x<list.size();x++){
if (list.get(x).getAge()==age){
activityList.add(listPos,list.get(x));
listPos++;
}
}
}
activitiesRecyclerAdapter = new ActivitiesRecyclerAdapter(activityList, context, new OnItemActivityClickListener() {
#Override
public void onItemClick(List<Activity> list, int position) {
Log.e("response_data","Click "+list.get(position).getName());
}
});
activityRecycler.setAdapter(activitiesRecyclerAdapter);
}
public void requestActivities(int age){
RequestMethods request = new RequestMethods(context);
request.onActivityResponse(this);
request.getActivities(skillId,babyId,age);
}
}
I have tried updating my Recyclerview using a the Override method getActivities(List<Activity> list, int age){} but nothing have worked till now. I have been stuck for hours please help!
Related
Conditions:
I have an Activity and I'm creating PagerAdapter extends FragmentPagerAdapter with one Fragment class. TabLayout includes 10 tabs. I have TabLayout.addOnTabSelectedListener and there in onTabSelected() I am updating some custom variable in app's SharedPreferences which depends on current tab name and tab index. Tab's names are not static - there are loading from server too.
My task:
With this value I should make a retrofit2 Call to my server and load values in adapter with recyclerview for my Fragment.
My problem:
I am loading the same data for the different tabs, which should contatin different data! I am understand that this happens because in all cases I have the same SharedPreferences variable's value so I am making retrofit Call with same conditions.
setOffscreenPageLimit() can't be setted to 0 - default is 1 according documentation:
https://developer.android.com/reference/kotlin/androidx/viewpager/widget/ViewPager#setoffscreenpagelimit;
setUserVisibleHint() on SO I've found this like some variant for solving my problem, but it can't be overrided because is deprecated now.
Solution:
I think I should save previous and next tab name in some way and then I can make different parallel retrofit Calls with different conditions. When tab selected I can get current, previous and next tab name. But how, where and when I should make two more retrofit calls?
UPD 08.02.2022: Still thinking about this problem.
Code:
SomeActivity.java
public class SomeActivity extends BaseActivity {
private String TAG="SomeActivity";
private Context context;
private TabLayout tabs;
private ViewPager viewpager;
private ProgressBar PBLoading;
private PagerAdapter_SomePAdapter adapter;
List<String> names = new ArrayList<>();
private String[] tabTitles;
public String previousTabName;
public String nextTabName;
public int counterForPreviousTabName;
public int counterForNextTabName;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_layout);
context = getApplicationContext();
String categories = AppPreferences.getCategories(context);
tabTitles = categories.split(";");
tabs = findViewById(R.id.tabs);
viewpager = findViewById(R.id.viewpager);
PBLoading = findViewById(R.id.PBLoading);
tabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
#Override
public void onTabSelected(TabLayout.Tab tab) {
Log.d(TAG, "onTabSelected");
AppPreferences.setCurrentValueForRetrofit(getApplicationContext(), tab.getPosition());
counterForPreviousTabName = tmpTab.getPosition() - 1;
counterForNextTabName = tmpTab.getPosition() + 1;
//here I can get tab names.
}
});
adapter = new PagerAdapter_SomePAdapter(getSupportFragmentManager(), SomeActivity.this);
viewpager.setAdapter(adapter);
adapter.updateTitleData(tabTitles);
tabs.setupWithViewPager(viewpager);
adapter.notifyDataSetChanged();
}
}
PagerAdapter_SomePAdapter.java:
public class PagerAdapter_SomePAdapter extends FragmentPagerAdapter {
int PAGE_COUNT = 2;
private String[] tabTitles = new String[] { "", ""};
private Context mContext;
Fragment_fragment fragment_fragment;
String TAG = "PagerAdapter_SomePAdapter";
public PagerAdapter_SomePAdapter(FragmentManager fm, Context context) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
mContext = context;
fragment_fragment = new Fragment_fragment();
}
#Override public int getCount() {
return PAGE_COUNT;
}
#Override public Fragment getItem(int position) {
return fragment_fragment.newInstance(position + 1, tabTitles[position]);
}
#Override public CharSequence getPageTitle(int position) {
return tabTitles[position];
}
public void updateTitleData(String[] tabTitlesNew) {
tabTitles = tabTitlesNew;
PAGE_COUNT = tabTitlesNew.length;
notifyDataSetChanged();
}
}
Fragment_fragment.java:
public class Fragment_fragment extends Fragment {
private String TAG = "Fragment_fragment";
private static final String ARG_PAGE = "ARG_PAGE";
private int mPage;
private View rootView;
private RecyclerView RV;
private Adapter_Items adapter;
public static Fragment_fragment newInstance(int page, String tabName) {
Bundle args = new Bundle();
args.putInt(ARG_PAGE, page);
Fragment_fragment fragment = new Fragment_fragment();
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mPage = getArguments().getInt(ARG_PAGE);
}
}
#Override
public void onAttach(#NonNull Context context) {
super.onAttach(context);
mContext=context;
}
#SuppressLint("ClickableViewAccessibility")
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.content_list, container, false);
RV = rootView.findViewById(R.id.recycler_view);
new loadDataAS().execute();
return rootView;
}
private void loadData(){
//retrofit call code;
}
class loadDataAS extends AsyncTask<Void, Void, Void> {
final ProgressDialog progress = new ProgressDialog(mContext);
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... arg0) {
loadData();
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
adapter = new Adapter_Items(arguments, arguments2, arguments3);
RV.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}
}
Adapter_Items:
public class Adapter_Items extends RecyclerView.Adapter<Adapter_Items.ViewHolder>{
private LayoutInflater mInflater;
private Context mContext;
private static String TAG = "Adapter_Items";
public Adapter_Items(List<Integer>arguments, List<String>arguments2, List<String>arguments3){
//initializing arguments
}
// inflates the row layout from xml when needed
#NotNull
#Override
public ViewHolder onCreateViewHolder(#NotNull ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.recycle_item, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
//setting view's information
}
#Override
public int getItemCount() {
return arguments.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
}
}
}
First thing,
fragment should contain different data
Saving tab name after tab selected will not work. You should remove this
AppPreferences.setCurrentValueForRetrofit(getApplicationContext(),
tab.getPosition());
You should call retrofit code inside the fragment with the tabName (Not from sharedPref) to get data for that tab.
For this, make the following changes,
You are already passing the tabName to fragment instance
newInstance(int page, String tabName)
use that tabName and pass to your AsyncTask -> loadData() as
loadData(tabName);
Then you can use that in your retrofit call and get the data.
Note:
setOffscreenPageLimit()
This method will load fragments just before they are completely visible. It would be useful and a great user experience to display data directly rather than fetching only when user selects the tab.
Let me quickly explain my code structure, I have a dynamic tab layout with a dynamic fragment. The tabs are fetched from a json response, and the each tab has a dynamic fragment with a recycler view populated from a json response as well.
I'm in trying to pass the id of the selected tab to the recycler view's adapter
1. TransactionsFragment(Where the tab layout is created)
for(int i=0;i<array.length();i++) {
//getting wallet object from json array
JSONObject userWallets=array.getJSONObject(i);
tab.addTab(tab.newTab().setText(userWallets.getString("wallet_name")));
walletID.add(userWallets.getInt("id"));
}
TransactionsPagerAdapter adapter = new TransactionsPagerAdapter
(getChildFragmentManager(), tab.getTabCount(), walletID); //the data i need to pass is the walletID
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tab));
adapter.notifyDataSetChanged();
2. TransactionsPagerAdapter(adapter controlling the tabs)
public class TransactionsPagerAdapter extends FragmentStatePagerAdapter {
int mNumOfTabs;
ArrayList<Integer> walletID;
public TransactionsPagerAdapter(FragmentManager fm, int NumOfTabs, ArrayList<Integer> walletID) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
this.mNumOfTabs = NumOfTabs;
this.walletID = walletID;
}
#Override
public Fragment getItem(int position) {
DynamicFragment d = new DynamicFragment();
Bundle args = new Bundle();
args.putInt("your_key", walletID.get(position));
d.setArguments(args);
return d.newInstance(walletID.get(position));
}
#Override
public int getCount() {
return mNumOfTabs;
}
}
3. DynamicFragment(Where recycler view in each tab is populated)
for(int i=0;i<array.length();i++) {
//getting wallet object from json array
JSONObject userTransactions=array.getJSONObject(i);
//adding the wallet to wallet list
userTransactionList.add(new Transaction(
userTransactions.getInt("id"),
userTransactions.getInt("wallet_id"),
userTransactions.getDouble("fee"),
userTransactions.getDouble("amount"),
userTransactions.getDouble("from"),
userTransactions.getDouble("to"),
userTransactions.getString("destination_address"),
userTransactions.getString("type"),
userTransactions.getString("created_at")
));
}
//creating adapter object and setting it to recyclerview
TransactionsAdapter adapter = new TransactionsAdapter(getActivity(),childFragmentManager, userTransactionList);
mRecyclerView.setAdapter(adapter);
swipeRefreshLayout.setRefreshing(false);
// stop animating Shimmer and hide the layout
mShimmerViewContainer.stopShimmerAnimation();
mShimmerViewContainer.setVisibility(View.GONE);
// progressDialog.dismiss();
adapter.notifyDataSetChanged();
4. TransactionsAdapter(adapter controlling the recycler views)
public class TransactionsAdapter extends RecyclerView.Adapter<TransactionsAdapter.DataObjectHolder> {
private static String TAG = TransactionsAdapter.class.getSimpleName();
private Context mCtx;
private FragmentManager fragmentManager;
private ArrayList<Transaction> userTransactionList;
private static MyClickListener myClickListener;
public TransactionsAdapter(Context mCtx, FragmentManager fragmentManager, ArrayList<Transaction> userTransactionList) {
this.mCtx = mCtx;
this.fragmentManager = fragmentManager;
this.userTransactionList = userTransactionList;
}
public static class DataObjectHolder extends RecyclerView.ViewHolder {
TextView transactionamount, transactionstatus, transactionid;
ImageView transactionicon, pendingicon;
public DataObjectHolder(View itemView) {
super(itemView);
transactionamount = (TextView) itemView.findViewById(R.id.amount);
transactionstatus = (TextView) itemView.findViewById(R.id.status);
transactionicon = (ImageView) itemView.findViewById(R.id.tx_icon);
pendingicon = (ImageView) itemView.findViewById(R.id.img_status);
transactionid = (TextView) itemView.findViewById(R.id.wallet_id);
}
}
#Override
public TransactionsAdapter.DataObjectHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mCtx).inflate(R.layout.transaction_item, parent, false);
final TransactionsAdapter.DataObjectHolder dataObjectHolder = new TransactionsAdapter.DataObjectHolder(view);
return dataObjectHolder;
}
#Override
public void onBindViewHolder(TransactionsAdapter.DataObjectHolder holder, final int position) {
DecimalFormat formatter = new DecimalFormat("###,###,###,###,###.##");
formatter.setDecimalSeparatorAlwaysShown(true);
formatter.setMinimumFractionDigits(2);
Double doubleBalance = userTransactionList.get(position).getTransactionAmount();
String numberFormatBalance = formatter.format(doubleBalance);
holder.transactionstatus.setText(userTransactionList.get(position).getTransactionType());
holder.transactionamount.setText(String.valueOf("₦ " + numberFormatBalance));
if ((userTransactionList.get(position).getTransactionType()).equals("send")) {
holder.transactionicon.setImageResource(R.drawable.ic_communication_call_made);
} else {
holder.transactionicon.setImageResource(R.drawable.ic_communication_call_received);
}
}
#Override
public int getItemCount() {
return userTransactionList.size();
}
public interface MyClickListener {
public void onItemClick(int position, View v);
}
}
I need to get the walletID from 1(TransactionsFragment) to 4(TransactionsAdapter), is this possible, if so how, I know for a fact this cannot be done with bundle since we aren't creating an intent
Make sure you put walletId to Arguments of DynamicFragment by
DynamicFragment.newInstance(walletID.get(position))
Modify constructor of TransactionsAdapter follow this
private Integer walletId;
public TransactionsAdapter(Context mCtx, FragmentManager fragmentManager, ArrayList<Transaction> userTransactionList, Integer walletId) {
this.mCtx = mCtx;
this.fragmentManager = fragmentManager;
this.userTransactionList = userTransactionList;
this.walletId = walletId;
}
In DynamicFragment when you init TransactionsAdapter get walletId from arguments of fragment
Integer walletId = getArguments().getInt("your_key") // your key when you newInstance and put to Bundle
TransactionsAdapter adapter = new TransactionsAdapter(getActivity(),childFragmentManager, userTransactionList);
Finally, your adapter has information of walletId
Need help with android app (java)
My app starts with SplashActivity. During it I`m getting json via retrofit request and after successfull response I fill my DB
SplashActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
ISplashInteractor splashInteractor = new SplashInteractor();
moviePresenter = new MoviePresenter(this, splashInteractor);
moviePresenter.initDB();
}
after DB successfully loaded automatically starts MovieListActivity
public class MovieListActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_movie_list);
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
Fragment allMoviesFragment = new AllMoviesFragment();
String tag = "MovieList";
transaction.replace(R.id.main_container, allMoviesFragment, tag);
transaction.commit();
}
}
and at once list of movies loads inside inner fragment AllMoviesFragment(inside recyclerView). till this point everything is ok.
now I set onRecyclerViewItemClickListener - it must open another fragment inside MovieListActivity but instead of this - my app restarts from begining and I observe loading of SpalshActivity again(I put progressbar during request) and again my RecyclerView...
my RecyclerViewAdapter
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
private List<MovieDetails> movieList;
private OnRecyclerViewItemClickListener onRecyclerViewItemClickListener;
public RecyclerViewAdapter(List<MovieDetails> movieList) {
this.movieList = movieList;
}
public void setOnRecyclerViewItemClickListener(OnRecyclerViewItemClickListener onRecyclerViewItemClickListener){
this.onRecyclerViewItemClickListener = onRecyclerViewItemClickListener;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.simple_selectable_list_item, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
MovieDetails movieDetails = (movieList.get(position));
holder.name.setText(movieDetails.getTitle());
holder.year.setText(String.valueOf(movieDetails.getReleaseYear()));
}
#Override
public int getItemCount() {
if (movieList == null)
return 0;
return movieList.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
TextView name;
TextView year;
public ViewHolder(View itemView) {
super(itemView);
name = itemView.findViewById(R.id.movie_name);
year = itemView.findViewById(R.id.release_year);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(onRecyclerViewItemClickListener != null){
int position = getAdapterPosition();
if(position != RecyclerView.NO_POSITION){
onRecyclerViewItemClickListener.onRecyclerViewItemClick(position);
}
}
}
});
}
}
public interface OnRecyclerViewItemClickListener {
void onRecyclerViewItemClick(int position);
}
}
my AllMoviesFragment
public class AllMoviesFragment extends Fragment implements RecyclerViewAdapter.OnRecyclerViewItemClickListener {
private static final String CURR_MOVIE = "Current Movie";
private static final String TAG = "MSApp";
List<MovieDetails> movieList;
RecyclerView recyclerView;
public AllMoviesFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
movieList = App.getAppInstance().getDatabaseInstance().getMovieDao().getAllMovies();
movieList.sort(new Comparator<MovieDetails>() {
#Override
public int compare(MovieDetails o1, MovieDetails o2) {
return o2.getReleaseYear() - o1.getReleaseYear();
}
});
View resultView = inflater.inflate(R.layout.fragment_all_movies, container, false);
recyclerView = resultView.findViewById(R.id.recycler_view);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
RecyclerViewAdapter adapter = new RecyclerViewAdapter(movieList);
adapter.setOnRecyclerViewItemClickListener(AllMoviesFragment.this);
recyclerView.setAdapter(adapter);
return resultView;
}
#Override
public void onRecyclerViewItemClick(int position) {
MovieDetails choosenMovie = movieList.get(position);
FragmentManager fragmentManager = getFragmentManager();
Fragment movieDetailsFragment = new MovieDetailsFragment();
Bundle args = new Bundle();
args.putParcelable(CURR_MOVIE, choosenMovie);
movieDetailsFragment.setArguments(args);
String tag = "MovieDetails";
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.main_container, movieDetailsFragment, tag);
transaction.addToBackStack(tag);
transaction.commit();
}
}
sorry for long post. I dont know how to cut it
I use App class for db access if it is important
#AkakiKapanadze
you was almost right
I didnot see the error message because it disappeared less 1 second
and class MovieDetailsFragment
after I remove binder of ButterKnife all work... I dont know WHY - I always use Butterknife inside Fragments
I'm trying to make a tab layout with each page having a RecyclerView inside of it. I'm using fragments with RecyclerView in them, then i put them inside of ViewPager. The problem is that even though tabs are being shown it's content is always empty.
My Activity class
public class Spells_Act extends AppCompatActivity {
private ViewPager pager;
private Spells_Slide slider;
private TabLayout tabLayout;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.spells);
tabLayout = findViewById(R.id.tab);
pager = findViewById(R.id.pager);
slider = new Spells_Slide(getSupportFragmentManager());
slider.AddFragment(new Fragment1(), "one");
slider.AddFragment(new Fragment1(), "two");
slider.AddFragment(new Fragment1(), "three");
pager.setAdapter(slider);
tabLayout.setupWithViewPager(pager);
}
}
My ViewPager adapter
public class Spells_Slide extends FragmentPagerAdapter {
private Context context;
LayoutInflater inflater;
private List<RecyclerView> pages;
private List<String> list = new LinkedList<>();
private final List<Fragment> stFragment = new ArrayList();
public Spells_Slide(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return stFragment.get(position);
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
return list.get(position);
}
#Override
public int getCount() {
return list.size();
}
#Override
public boolean isViewFromObject(#NonNull View view, #NonNull Object
object) {
return false;
}
public void AddFragment(Fragment fragment, String title) {
list.add(title);
stFragment.add(fragment);
}
My Fragment class
public class Fragment1 extends Fragment {
View v;
private RecyclerView recycler;
Adapter_Rec adapter;
private List<Spells> Spells = new LinkedList<>();
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Spells.add(new Spells("Ghost Sound", "Figment sounds", 0));
Spells.add(new Spells("Disrupt Undead", " Deals 1d6 damage to one undead", 0));
Spells.add(new Spells("Resistance", "Subject gains +1 on saving throws", 0));
Spells.add(new Spells("Ray of Frost", "Ray deals 1d3 cold damage", 0));
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
v = inflater.inflate(R.layout.frag1, container, false);
recycler = v.findViewById(R.id.frag_recycler);
recycler.setLayoutManager(new LinearLayoutManager(getActivity()));
adapter = new Adapter_Rec(Spells, getContext());
recycler.setAdapter(adapter);
return v;
}
}
And finally my RecyclerViewAdapter
public class Adapter_Rec extends
RecyclerView.Adapter<Adapter_Rec.MyViewHolder> {
private List<Spells> list = new LinkedList<>();
Context context;
public Adapter_Rec(List<Spells> list, Context context)
{
this.context=context;
this.list=list;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v;
v = LayoutInflater.from(context).inflate
(R.layout.spells_recycle,parent,false);
MyViewHolder vholder = new MyViewHolder(v);
return vholder;
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.check.setOnCheckedChangeListener(null);
holder.name.setText(list.get(position).getName());
holder.benefits.setText(list.get(position).getDescription());
}
#Override
public int getItemCount() {
return list.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder
{
TextView name;
TextView benefits;
CheckBox check ;
public MyViewHolder(View item)
{ super(item);
name = item.findViewById(R.id.namee);
benefits = item.findViewById(R.id.desc);
check =item.findViewById(R.id.check);
}
}
}
delete isViewFromObject method, or return super.isViewFromObject(view, object);
#Override
public boolean isViewFromObject(#NonNull View view, #NonNull Object
object) {
//return false; // return false will never show this fragment
return super.isViewFromObject(view, object);
}
I am trying to implement RecyclerView inside a Fragment. I have designed a CustomAdapter(StateAdapter) class to load the contents of RecyclerView and an interface StateAdapterOnClickHandler to handle onClicks of the items inside RecyclerView but clicking on item doesn't work.
Here's my HomeFragment.java which extends Fragment. I am unable to figure out how to initialize the StateAdapterOnClickHandler and where to call its method onItemClick()
public class HomeFragment extends Fragment implements StateAdapter.StateAdapterOnClickHandler {
private View homeFragment;
private RecyclerView recyclerView;
private StateAdapter stateAdapter;
private List<String> states;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public static HomeFragment newInstance() {
HomeFragment homeFragment = new HomeFragment();
return homeFragment;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
homeFragment = inflater.inflate(R.layout.fragment_home,container,false);
recyclerView = homeFragment.findViewById(R.id.recyclerview_states);
states = Arrays.asList(getResources().getStringArray(R.array.india_states));
LinearLayoutManager layoutManager = new LinearLayoutManager(container.getContext(),LinearLayoutManager.VERTICAL,false);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
stateAdapter = new StateAdapter();
stateAdapter.setStateNames(states);
recyclerView.setAdapter(stateAdapter);
return homeFragment;
}
#Override
public void onItemClick(String state) {
Intent intent = new Intent(getActivity(),DetailActivity.class);
intent.putExtra("State",state);
startActivity(intent);
}
}
Here's my StateAdapter class
public class StateAdapter extends RecyclerView.Adapter<StateAdapter.StateViewHolder> {
private List<String> stateNames;
private final StateAdapterOnClickHandler stateAdapterOnClickHandler;
StateAdapter(StateAdapterOnClickHandler stateAdapterOnClickHandler){
this.stateAdapterOnClickHandler = stateAdapterOnClickHandler;
}
public interface StateAdapterOnClickHandler {
void onItemClick(String state);
}
#Override
public StateAdapter.StateViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
int idForListItem = R.layout.state_layout;
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(idForListItem,parent,false);
return new StateViewHolder(view);
}
#Override
public void onBindViewHolder(StateAdapter.StateViewHolder holder, int position) {
String stateName = stateNames.get(position);
holder.mTextView.setText(stateName);
}
#Override
public int getItemCount() {
if(stateNames == null) return 0;
return stateNames.size();
}
public class StateViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public final TextView mTextView;
public StateViewHolder(View itemView) {
super(itemView);
mTextView = (TextView) itemView.findViewById(R.id.tv_state_name);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
int clickedPostion = getAdapterPosition();
String state = stateNames.get(clickedPostion);
stateAdapterOnClickHandler.onItemClick(state);
}
}
public void setStateNames(List<String> states) {
stateNames = states;
notifyDataSetChanged();
}
}
Please, tell me what's wrong with the code while handling the clicks. I am new to Android Programming and this is first time I am working with Fragments. Thanks for helping.