How to acces SharedPrefences from recyclerView adapter? - android

I want to acces SharedPrefences from my adapter because I want to check a variable to set an ImageView visible or gone.
class MainAdapter extends RecyclerView.Adapter<MainAdapter.ViewHolder> implements View.OnClickListener, View.OnLongClickListener{
ArrayList<String> mData;
public ImageView mMinus;
public static final String SHARED_PREFS_DATA = "sharedPrefsData";
public MainAdapter(ArrayList<String> data) {
mData = data;
}
#NonNull
#Override
public MainAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MainAdapter.ViewHolder holder, int position) {
holder.mText.setText(mData.get(position));
SharedPreferences sharedPreferences = getSharedPreferences(SHARED_PREFS_DATA, 0);
int a = sharedPreferences.getInt("visible", 0);
if(a == 0)
holder.mMinus.setVisibility(View.GONE);
else
holder.mMinus.setVisibility(View.VISIBLE);
}
error: cannot find symbol method getSharedPreferences(String,int)

1.Pass the context from the Activity to the adapter and using this context you can access the shared preferences
2.You can also pass the Activity reference instead of Context

Related

How to get shared prefs in Adapter class, Firebase

I Get data from firebase into a recycler view, In my Adapter class I want to get a Data which is stored in my Shared Prefs, How can I get the Data which is in my Shared Prefs into my Firebase Adapter Activity !
MY ADAPTER CLASS
public class Chat_Adapter extends
FirebaseRecyclerAdapter<Chat_Model,Chat_Adapter.myViewHolder> {
public Chat_Adapter(#NonNull FirebaseRecyclerOptions<Chat_Model> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull myViewHolder holder, int position, #NonNull Chat_Model model) {
holder.date.setText(model.getDate());
holder.uname.setText(model.getUname());
holder.msg.setText(model.getMsg());
}
#NonNull
#Override
public myViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_item, parent, false);
return new myViewHolder(view);
}
class myViewHolder extends RecyclerView.ViewHolder {
TextView uname, date,msg;
public myViewHolder(#NonNull View itemView) {
super(itemView);
uname = itemView.findViewById(R.id.named);
date = itemView.findViewById(R.id.date);
msg = itemView.findViewById(R.id.message);
}
}
}
I have a data coming from my Database which (model.getUname), What i want to do is to my original name from my Shared Prefs and check if (model.getUname == myname).
Get Context inside onCreateViewHolder() method and save it in your field variable and then use it inside onBindViewHolder() and get shared prefs there
public class Chat_Adapter extends FirebaseRecyclerAdapter<Chat_Model, Chat_Adapter.myViewHolder> {
private Context context;
public Chat_Adapter(#NonNull FirebaseRecyclerOptions<Chat_Model> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull myViewHolder holder, int position, #NonNull Chat_Model model) {
//here is your shared pref
SharedPreferences your_shared_pref_name = context.getSharedPreferences("YOUR_SHARED_PREF_NAME", Context.MODE_PRIVATE);
holder.date.setText(model.getDate());
holder.uname.setText(model.getUname());
holder.msg.setText(model.getMsg());
}
#NonNull
#Override
public myViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_item, parent, false);
context = parent.getContext();
return new myViewHolder(view);
}
class myViewHolder extends RecyclerView.ViewHolder {
TextView uname, date, msg;
public myViewHolder(#NonNull View itemView) {
super(itemView);
uname = itemView.findViewById(R.id.named);
date = itemView.findViewById(R.id.date);
msg = itemView.findViewById(R.id.message);
}
}
}

Merging two mostly similar adapters for recyclerview

I have two adapters that adapt to a recycler view depending on different conditions. I want to merge them.
The issue is that I created first in the same file as the activity where it is being used and the other is in a new file.
Take it as follows:
DefaultAdapter is in the file where it is being used.
AutoCompleteAdapter is also used in the same file but is declared in other file.
I want to get rid of Default Adapter and get its funtions into AutoCompleteAdapter.
There are some issues to it: I can no more use the ParentFiles' variables.
Below is the adapter that I want to get rid of.
public class DefaultAdapter extends RecyclerView.Adapter<DefaultAdapter.ViewHolder> {
private Context context;
private AdapterView.OnItemClickListener onItemClickListener;
List<String> searchList;
#NonNull #Override
public DefaultAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = (View) LayoutInflater.from(parent.getContext())
.inflate(android.R.layout.simple_list_item_1, null);
ViewHolder holder = new ViewHolder(view);
return holder;
}
#Override public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.txt.setText(
Html.fromHtml(getItem(position)).toString());///need to get rid of this error
}
#Override public int getItemCount() {
return searchList.size();
}
#NonNull public String getItem(int position) {
return searchList.get(position);
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView txt;
public ViewHolder(#NonNull View itemView) {
super(itemView);
txt = itemView.findViewById(android.R.id.text1);
itemView.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View v) {
String title = txt.getText().toString();
searchPresenter.saveSearch(title);
}
});
itemView.setOnLongClickListener(new View.OnLongClickListener() {
#Override public boolean onLongClick(View v) {
String searched = txt.getText().toString();
deleteSpecificSearchDialog(searched);
return true;
}
});
}
}
}
Please take note of the SearchPresenter. This is a variable in the parent file, that is causing major issues. Autocomplete adapter doesn't have to use it, but default have to.
This is the adapter I want it to merge into
public class AutoCompleteAdapter extends RecyclerView.Adapter<AutoCompleteAdapter.ViewHolder>
implements Filterable {
#Inject JNIKiwix currentJNIReader;
#Inject SharedPreferenceUtil sharedPreferenceUtil;
#Inject ZimReaderContainer zimReaderContainer;
private List<String> data;
private KiwixFilter kiwifilter;
private Context context;
public AutoCompleteAdapter(Context context) {
this.context = context;
data = new ArrayList<>();
kiwifilter = new KiwixFilter();
setupDagger();
}
private void setupDagger() {
CoreApp.getCoreComponent().inject(this);
}
#NonNull #Override public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = (View) LayoutInflater.from(parent.getContext())
.inflate(android.R.layout.simple_list_item_1, null);
ViewHolder holder = new ViewHolder(view);
return holder;
}
#Override public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.title.setText(Html.fromHtml(getItem(position)).toString());
}
#Override
public String getItem(int index) {
String a = data.get(index);
if (a.endsWith(".html")) {
String trim = a.substring(2);
trim = trim.substring(0, trim.length() - 5);
return trim.replace("_", " ");
} else {
return a;
}
}
#Override public int getItemCount() {
return data.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView title;
public ViewHolder(#NonNull View itemView) {
super(itemView);
title = itemView.findViewById(android.R.id.text1);
}
}
}
...
Note the similarity between the two, they are almost similar, autocompleteadapter is like superset of defaultadapter.
I just want to get rid of the default adapter.
Note: I have chopped off some other things from autocompeleteadapter, I think they are not required for the problem.
Noob here...
Thanks

Android notifyDataSetChanged for nested Adapter doesn't work

In my SectionsListAdapter adapter i have nested Adapter named MonthLessonsList, after get date from web service and set new data and call notifyDataSetChanged method for adapter, main adapter as SectionsListAdapter can be refresh, but nested adapter dont refresh and after calling notifyDataSetChanged for that, doesn't work correctly and don't show new data
call and set new data from Fragment:
monthSectionsItems = SQLite.select().from(MonthSections.class).queryList();
adapter.setData(monthSectionsItems);
and my Adapter with nested adapter:
public class SectionsListAdapter extends RecyclerView.Adapter<SectionsListAdapter.MyViewHolder> {
private final OnItemSelected listener;
private List<MonthSections> list;
private Context context;
private MonthLessonsList lessonsListAdapter;
public SectionsListAdapter(List<MonthSections> followingsList, Context mContext, OnItemSelected listener) {
this.list = followingsList;
this.context = mContext;
this.listener = listener;
}
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.sections_list_row, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull final MyViewHolder holder, final int position) {
holder.indicatorIcon.setText(list.get(position).getSection_month_name());
...
List<SectionLesson> lessonsList = list.get(position).getLessons();
lessonsListAdapter = new MonthLessonsList(lessonsList);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(context);
holder.userChildCategories.setLayoutManager(mLayoutManager);
holder.userChildCategories.setAdapter(lessonsListAdapter);
...
}
#Override
public int getItemCount() {
return list.size();
}
public void setData(List<MonthSections> data) {
list.clear();
list.addAll(data);
notifyDataSetChanged();
lessonsListAdapter.notifyDataSetChanged();
}
public List<MonthSections> getData() {
return list;
}
class MyViewHolder extends RecyclerView.ViewHolder {
...
public MyViewHolder(View view) {
super(view);
ButterKnife.bind(this, view);
section_title.setGravity(Gravity.RIGHT);
}
}
public class MonthLessonsList extends RecyclerView.Adapter<MonthLessonsList.LessonsViewHolder> {
private List<SectionLesson> lessonItem;
public class LessonsViewHolder extends RecyclerView.ViewHolder {
public TextView title;
public LessonsViewHolder(View view) {
super(view);
title = view.findViewById(R.id.title);
}
}
public MonthLessonsList(List<SectionLesson> lists) {
this.lessonItem = lists;
}
#Override
public LessonsViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.child_list_row, parent, false);
return new LessonsViewHolder(itemView);
}
#SuppressLint("SetTextI18n")
#Override
public void onBindViewHolder(#NonNull LessonsViewHolder holder, int position) {
SectionLesson lesson = lessonItem.get(position);
holder.title.setText("درس: " + (position + 1) + ") " + lesson.getTitle());
}
#Override
public int getItemCount() {
return lessonItem.size();
}
}
}
Declare child adapter inside onBindViewHolder, and remove from global level.
And no need to notify child adapter. Because that will be automatically filled when parent onBindViewHolder is called.
Like
MonthLessonsList lessonsListAdapter = new MonthLessonsList(lessonsList);
holder.userChildCategories.setAdapter(lessonsListAdapter);

How to change RecyclerView items color from MainActivity?

I have an app which has a recyclerview. I want to give an opportunity to the users to switch between Night and Day mode theme. I know how to change text color and background color, but in this case I can't. Actually I am unable to find the item layout variables from MainActivity. How to create an object of ViewHolder class from MainActivity? Can anyone please help me?
Here is my Adapter class:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>{
private List<ListItemModel> listItems;
private Context context;
public MyAdapter(List<ListItemModel> listItems, Context context) {
this.listItems = listItems;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_model, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
final ListItemModel listItem = listItems.get(position);
holder.index_number.setText(listItem.getIndexNumber());
holder.title_name.setText(listItem.getTitle());
}
#Override
public int getItemCount() {
return listItems.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView index_number, title_name;
public ViewHolder(View itemView) {
super(itemView);
index_number = (TextView) itemView.findViewById(R.id.model_text_index_id);
title_name = (TextView) itemView.findViewById(R.id.model_text_title_id);
}
}
}
If its a single choice list, you can define an int parameter in your list and define a method in adapter
....
private int selectedPosition = -1;
public void setSelectedPosition(int index){
selectedPosition = index;
notifyItemChanged(selectedPosition)
}
then in OnBindViewHolder do this:
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
final ListItemModel listItem = listItems.get(position);
holder.index_number.setText(listItem.getIndexNumber());
holder.title_name.setText(listItem.getTitle());
if(position == selectedPosition){
holder.index_number.setTextColor(MY_COLOR)
holder.title_name.setTextColor(MY_COLOR)
} else {
holder.index_number.setTextColor(NORMAL_COLOR)
holder.title_name.setTextColor(NORMAL_COLOR)
}
}
For multi selected list, you can define a parameter like isChosen in your ListItemModel and change that parameter to true and false and in your OnBindViewHolder check that parameter
I found the solution of your problem
Create a method inside your activity and call when click on item in adapter and send position
public void click(int position) {
TestAdapter.ViewHolder viewHolder = (TestAdapter.ViewHolder) recyclerView.findViewHolderForAdapterPosition(position);
viewHolder.text_color.setTextColor(Color.parseColor("#245251"));
}
Hope this will help you.

How to send data from recycler adapter to fragment | How to call fragment function from recyclerview adapter

I have code in Fragment:
InfoAdapter adapter = new InfoAdapter(getContext(), R.layout.lv_info, infoList );
listingsView = (RecyclerView) rootView.findViewById(R.id.lvInfo);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext());
listingsView.setLayoutManager(layoutManager);
listingsView.setHasFixedSize(true);
listingsView.setAdapter(adapter);
How do I process clicks on an items in this fragment?
Eg call function (function located in fragment) with ID item (eg public void onItemClick(int item_id) {} )
My adapter:
public class InfoAdapter extends RecyclerView.Adapter<InfoHolder> {
private final List<Info> infos;
private Context context;
private int itemResource;
public InfoAdapter(Context context, int itemResource, List<Info> infos) {
this.infos = infos;
this.context = context;
this.itemResource = itemResource;
}
#Override
public InfoHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(this.itemResource, parent, false);
return new InfoHolder(this.context, view);
}
#Override
public void onBindViewHolder(InfoHolder holder, int position) {
Info info = this.infos.get(position);
holder.bindInfo(info);
}
#Override
public int getItemCount() {
return this.infos.size();
}
}
You can use interface to achieve your desired result.
Just declare an interface in your adapter with the parameters that you want to pass to your fragment. And in your fragment initialize the interface and pass it to your adapter's constructor.
You can do something like this:
In your Fragment
public class MainFragment extends Fragment {
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Pass your adapter interface in the constructor
InfoAdapter adapter = new InfoAdapter(getContext(), R.layout.lv_info, infoList, adapterInterface );
}
// This is the interface declared inside your adapter.
InfoAdapter.InfoAdapterInterface adapterInterface = new InfoAdapter.InfoAdapterInterface() {
#Override
public void OnItemClicked(int item_id) {
// Do whatever you wants to do with this data that is coming from your adapter
}
};
}
In your Adapter
public class InfoAdapter extends RecyclerView.Adapter<InfoHolder> {
private final List<Info> infos;
private Context context;
private int itemResource;
// Interface Object
private InfoAdapterInterface adapterInterface;
public InfoAdapter(Context context, int itemResource, List<Info> infos, InfoAdapterInterface adapterInterface) {
this.infos = infos;
this.context = context;
this.itemResource = itemResource;
// Initialize your interface to send updates to fragment.
this.adapterInterface = adapterInterface;
}
#Override
public InfoHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(this.itemResource, parent, false);
return new InfoHolder(this.context, view);
}
#Override
public void onBindViewHolder(InfoHolder holder, int position) {
Info info = this.infos.get(position);
holder.bindInfo(info);
// You can pass any data here that is defined in your interface's params
adapterInterface.OnItemClicked(3);
}
#Override
public int getItemCount() {
return this.infos.size();
}
// Your interface to send data to your fragment
public interface InfoAdapterInterface{
void OnItemClicked(int item_id);
}
}
You can create multiple methods in your interface and can easily get the desired data inside your interface. Another trick can be using Abstract methods.
I hope this will help you. Let me know if you face any difficulty :)
Edit to show how to pass Interface from Adapter to ViewHolder
In your Adapter Class do this
#Override
public InfoHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(this.itemResource, parent, false);
// Pass the interface that you've created in the constructor of your viewholder
return new InfoHolder(view, adapterInterface);
}
And in your ViewHolder you can get the interface like this and use it wherever you want inside your ViewHolder:
public class InfoHolder extends RecyclerView.ViewHolder {
public InfoHolder(View itemView, final InfoAdapter.InfoAdapterInterface adapterInterface) {
super(itemView);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
adapterInterface.OnItemClicked(2);
}
});
}
}
This should solve your problem with interfaces ^_^
In your method onBindViewHolder, set the onclicklistener in the binded view and pass its parameters trough Bundle.
Just pass Fragment instance to adapter.
For example :
IN FRAGMENT :
recyclerAdapter = new RecyclerAdapter(getActivity(), MyFragment.this);
recyclerView.setAdapter(recyclerAdapter);
recyclerAdapter.notifyDataSetChanged();
IN ADAPTER :
1. Create adapter constructer like
MyFragment myFragment;
public RecyclerAdapter(Context context, MyFragment myFragment){
this.context = context;
this.myFragment = myFragment;
}
under onBindViewHolder
call myFragment.yourMethodName;

Categories

Resources