I created an app which displays all files from internal storage in gridview using recyclerviewadapter. But I am not sure how to display different icons for different file types. I want to achieve somewhat this kind of view. Like it has different icon for a folder, different for a pdf file, or an image. How can I achieve this ?
InternalStorage.java:
public class InternalStorage extends AppCompatActivity implements MyRecyclerViewAdapter.ItemClickListener {
MyRecyclerViewAdapter adapter;
private ArrayList<String> myList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_internal_storage);
myList = new ArrayList<>();
String path= Environment.getExternalStorageDirectory().getAbsolutePath();
File f = new File(path);//converted string object to file
File list[] = f.listFiles();//getting the list of files in string array
for( int i=0; i< list.length; i++) {
myList.add(list[i].getName());
}
// set up the RecyclerView
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.rvNumbers);
int numberOfColumns = 4;
recyclerView.setLayoutManager(new GridLayoutManager(this, numberOfColumns));
adapter = new MyRecyclerViewAdapter(this, myList);
adapter.setClickListener(this);
recyclerView.setAdapter(adapter);
}
}
MyRecyclerViewAdapter.java:
public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder> {
private ArrayList<String> mData;
private LayoutInflater mInflater;
private ItemClickListener mClickListener;
// data is passed into the constructor
public MyRecyclerViewAdapter(Context context, ArrayList<String> data) {
this.mInflater = LayoutInflater.from(context);
this.mData = data;
}
// inflates the cell layout from xml when needed
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.recyclerview_item, parent, false);
return new ViewHolder(view);
}
// binds the data to the textview in each cell
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
String animal = mData.get(position);
holder.myTextView.setText(animal);
}
// total number of cells
#Override
public int getItemCount() {
return mData.size();
}
// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView myTextView;
ImageButton myImage;
ViewHolder(View itemView) {
super(itemView);
myTextView = (TextView) itemView.findViewById(R.id.info_text);
myImage = (ImageButton) itemView.findViewById(R.id.buttonimage);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
}
}
// convenience method for getting data at click position
public String getItem(int id) {
return mData.get(id);
}
// allows clicks events to be caught
public void setClickListener(ItemClickListener itemClickListener) {
this.mClickListener = itemClickListener;
}
// parent activity will implement this method to respond to click events
public interface ItemClickListener {
void onItemClick(View view, int position);
}
}
first of all you need to creat a model than allows you to diferentiate each animal from the others. You can do it with a model wich has a name and a imageUrl (an image url to each animal than you can set depending of the type of the animal). After that you must define a imageView who will have the new image (the one that will be inflatin with the image you bring from the url). To load the image i recomend to you to use Picasso, whihc is a library that makes easier to load any kind of imagen.
The code is somethin like this
public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder> {
private ArrayList<Animal> mData;
private LayoutInflater mInflater;
private ItemClickListener mClickListener;
// data is passed into the constructor
public MyRecyclerViewAdapter(Context context, ArrayList<String> data) {
this.mInflater = LayoutInflater.from(context);
this.mData = data;
}
// inflates the cell layout from xml when needed
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.recyclerview_item, parent, false);
return new ViewHolder(view);
}
// binds the data to the textview in each cell
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Animal animal = mData.get(position);
holder.myTextView.setText(animal);
Picasso.with(context).load(animal.imageUrl).into(holder.imageViewYouWantToChangue)
}
// total number of cells
#Override
public int getItemCount() {
return mData.size();
}
// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView myTextView;
ImageButton myImage;
ViewHolder(View itemView) {
super(itemView);
myTextView = (TextView) itemView.findViewById(R.id.info_text);
myImage = (ImageButton) itemView.findViewById(R.id.buttonimage);
imageViewYouWantToChangue = (ImageView) itemView.findViewById(R.id.image_you_to_changue);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
}
}
// convenience method for getting data at click position
public String getItem(int id) {
return mData.get(id);
}
// allows clicks events to be caught
public void setClickListener(ItemClickListener itemClickListener) {
this.mClickListener = itemClickListener;
}
// parent activity will implement this method to respond to click events
public interface ItemClickListener {
void onItemClick(View view, int position);
}
}}
public class Animal{
String name;
String imageUrl;
public Animal(String name, String type) {
this.name = name;
this.imageUrl = imageUrl;
}
}
The info about picasso
http://square.github.io/picasso/
And don't forget to add the INTERNET_PERMISION to you app in the manifest.
Related
I already know how a recycler viewer works and a good understanding of interface listeners but I'm wondering why is it that we need to pass a listener to my recycler adapter called mAdapter = new GreenAdapter. In my MainActivity.java I have something like this
public class MainActivity extends AppCompatActivity implements GreenAdapter.ListItemClickListener {
private static final int NUM_LIST_ITEMS = 100;
private GreenAdapter mAdapter;
private RecyclerView mNumbersList;
private Toast mToast;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAdapter = new GreenAdapter(NUM_LIST_ITEMS, this);
mNumbersList.setAdapter(mAdapter);
}
#Override
public void onListItemClick(int clickedItemIndex) {
String toastMessage = "Item #" + clickedItemIndex + "clicked.";
mToast = Toast.makeText(this, toastMessage, Toast.LENGTH_LONG);
mToast.show();
}
In my GreenAdapter.java I understand that my Viewholder constructor will invoke my custom interface called ListItemClickedListener passing in the position of the clicked view and from there I can implement the code for what will happen when the user clicks it through my onListItemClick abstract method
public class GreenAdapter extends RecyclerView.Adapter<GreenAdapter.NumberViewHolder> {
private static final String TAG = GreenAdapter.class.getSimpleName();
private int mNumberItems;
final private ListItemClickListener mOnClickListener;
public interface ListItemClickListener{
void onListItemClick(int clickedItemIndex);
}
public GreenAdapter(int numberOfItems, ListItemClickListener listener) {
mNumberItems = numberOfItems;
mOnClickListener = listener;
}
#Override
public NumberViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
Context context = viewGroup.getContext();
int layoutIdForListItem = R.layout.number_list_item;
LayoutInflater inflater = LayoutInflater.from(context);
boolean shouldAttachToParentImmediately = false;
View view = inflater.inflate(layoutIdForListItem, viewGroup, shouldAttachToParentImmediately);
NumberViewHolder viewHolder = new NumberViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(NumberViewHolder holder, int position) {
Log.d(TAG, "#" + position);
holder.bind(position);
}
#Override
public int getItemCount() {
return mNumberItems;
}
class NumberViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView listItemNumberView;
public NumberViewHolder(View itemView) {
super(itemView);
listItemNumberView = (TextView) itemView.findViewById(R.id.tv_item_number);
itemView.setOnClickListener(this);
}
void bind(int listIndex) {
listItemNumberView.setText(String.valueOf(listIndex));
}
#Override
public void onClick(View view) {
int clickedPosition = getAdapterPosition();
mOnClickListener.onListItemClick(clickedPosition);
}
}
I'm just confuse why we need to pass this in my recycler adapter
By passing this you are actually passing the object of MainActivity.java which is implementing GreenAdapter.ListItemClickListener interface. Now when your user clicks on item you can let your activity know what item in the list was clicked by the user the rest of Business logic will then be written in the onListItemClick() method of MainActivity.
I'm trying to populate a RecyclerView using data stored in a ArrayList. When the RecyclerView loads each piece of data is repeted 4x in each row.
I've tried a whole variety of solutions I've found, but none seem to resolve the issue.
After some debugging the data in 'mData', appears to be correct, so that would lead me to believe that this issue is 'onBindViewHolder'?
Adapter
public class EventsRecyclerViewAdapter extends RecyclerView.Adapter<EventsRecyclerViewAdapter.ViewHolder> {
private List<String> mData;
private LayoutInflater mInflater;
private ItemClickListener mClickListener;
// data is passed into the constructor
public EventsRecyclerViewAdapter(List<String> data) {
this.mInflater = LayoutInflater.from(MainActivity.mainActivity);
this.mData = data;
}
// inflates the row layout from xml when needed
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.recyclerview_row, parent, false);
return new ViewHolder(view);
}
// binds the data to the TextView in each row
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.keyID.setText(mData.get(position));
holder.lockID.setText(mData.get(position));
holder.eventTime.setText(mData.get(position));
holder.eventType.setText(mData.get(position));
}
// total number of rows
#Override
public int getItemCount() {
return mData.size();
}
// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView keyID;
TextView lockID;
TextView eventTime;
TextView eventType;
ViewHolder(View itemView) {
super(itemView);
keyID = itemView.findViewById(R.id.keyIDTV);
lockID = itemView.findViewById(R.id.lockIDTV);
eventTime = itemView.findViewById(R.id.eventDateTV);
eventType = itemView.findViewById(R.id.eventTypeTV);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
}
}
// parent activity will implement this method to respond to click events
public interface ItemClickListener {
void onItemClick(View view, int position);
}
Fragment
public class KeyEvents extends Fragment {
public static KeyInfo newInstance() {
KeyInfo fragment = new KeyInfo();
return fragment;
}
EventsRecyclerViewAdapter adapter;
ArrayList<String> eventsList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EventsOperationHandler ev = new EventsOperationHandler();
eventsList = new ArrayList<>();
for (int i=0; i<ev.getEvents().size(); i++) {
eventsList.add(ev.getEvents().get(i).get(0));
eventsList.add(ev.getEvents().get(i).get(1));
eventsList.add(ev.getEvents().get(i).get(2));
eventsList.add(ev.getEvents().get(i).get(3));
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_event_info, container, false);
RecyclerView recyclerView = view.findViewById(R.id.rvEvents);
recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.mainActivity));
adapter = new EventsRecyclerViewAdapter(eventsList);
recyclerView.setAdapter(adapter);
return view;
}
}
In your 'onBindViewHolder' you are setting same data in every textView of yours
// binds the data to the TextView in each row
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.keyID.setText(mData.get(position));
holder.lockID.setText(mData.get(position));
holder.eventTime.setText(mData.get(position));
holder.eventType.setText(mData.get(position));
}
Here you are setting mData.get(position) to every textView in the holder
A solution would be creating a Pojo class for your recyclerView
Create Pojo Event class
class Event{
public String keyID;
public String lockID;
public String eventTime;
public String eventType;
}
Create a list of 'Event' in your fragment
public class KeyEvents extends Fragment {
public static KeyInfo newInstance() {
KeyInfo fragment = new KeyInfo();
return fragment;
}
EventsRecyclerViewAdapter adapter;
ArrayList<Event> eventsList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EventsOperationHandler ev = new EventsOperationHandler();
eventsList = new ArrayList<>();
for (int i=0; i<ev.getEvents().size(); i++) {
Event event = new Event();
event.keyID = ev.getEvents().get(i).get(0);
event.lockID = ev.getEvents().get(i).get(1);
event.eventTime = ev.getEvents().get(i).get(2);
event.eventType = ev.getEvents().get(i).get(3);
eventsList.add(event);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_event_info, container, false);
RecyclerView recyclerView = view.findViewById(R.id.rvEvents);
recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.mainActivity));
adapter = new EventsRecyclerViewAdapter(eventsList);
recyclerView.setAdapter(adapter);
return view;
}
}
Modify your recyclerView to handle to 'Event' class
public class EventsRecyclerViewAdapter extends RecyclerView.Adapter<EventsRecyclerViewAdapter.ViewHolder> {
private List<Event> mData;
private LayoutInflater mInflater;
private ItemClickListener mClickListener;
// data is passed into the constructor
public EventsRecyclerViewAdapter(List<Event> data) {
this.mInflater = LayoutInflater.from(MainActivity.mainActivity);
this.mData = data;
}
// inflates the row layout from xml when needed
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.recyclerview_row, parent, false);
return new ViewHolder(view);
}
// binds the data to the TextView in each row
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Event event = mData.get(position);
holder.keyID.setText(event.keyID);
holder.lockID.setText(event.lockId);
holder.eventTime.setText(event.eventTime);
holder.eventType.setText(event.eventType);
}
// total number of rows
#Override
public int getItemCount() {
return mData.size();
}
// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView keyID;
TextView lockID;
TextView eventTime;
TextView eventType;
ViewHolder(View itemView) {
super(itemView);
keyID = itemView.findViewById(R.id.keyIDTV);
lockID = itemView.findViewById(R.id.lockIDTV);
eventTime = itemView.findViewById(R.id.eventDateTV);
eventType = itemView.findViewById(R.id.eventTypeTV);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
}
}
// parent activity will implement this method to respond to click events
public interface ItemClickListener {
void onItemClick(View view, int position);
}
That's it, this should work perfectly.
I am actually working on a group project and I want to develop a functionnality for our application. My goal is to have a list of several items with their images and when I click on an Item of that list I want to have a text pop in the midle of the screen related to that particular item. I'm afraid I might be using the wrong technical Tools to do so. I am actually using a csv file for the list details, an adapter and a viewHolder for the list. Since I have no idea on what is wrong and what to do I link a big part of my code so you can check how I did until now. I can also give you my xml files if you need to check them out, a really big thanks in advance to all the answers and time spent on my problem
I already managed to have my list of items with the title and the picture (text from csv file) of each list item but I'm stuck on how to show a specific text for each ViewHolder.
this is my Adapter
public class Adapter extends RecyclerView.Adapter<ViewHolder> {
List<Departement> list;
Activity activity;
public Adapter(List<Departement> list, Activity activity) {
this.list = list;
this.activity = activity;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int itemType) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.departement,viewGroup,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
Departement departement = list.get(position);
viewHolder.bind(departement, activity);
}
#Override
public int getItemCount() {
return list.size();
}
}
my ViewHolder
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView textViewView;
private ImageView imageView;
public ViewHolder(View itemView) {
super(itemView);
textViewView = (TextView) itemView.findViewById(R.id.text);
imageView = (ImageView) itemView.findViewById(R.id.image);
}
public void bind(Departement departement, Activity activity){
textViewView.setText(departement.getText());
String uri = departement.getImageUrl();
int imageResource = activity.getResources().getIdentifier(uri, null, activity.getPackageName());
Drawable res = activity.getResources().getDrawable(imageResource);
imageView.setImageDrawable(res);
}
}
each item of the list is a Departement
public class Departement {
private String text;
private String imageUrl;
public Departement(String text, String imageUrl) {
this.text = text;
this.imageUrl = imageUrl;
}
public String getText() {
return text;
}
public String getImageUrl() {
return imageUrl;
}
public void setText(String text) {
this.text = text;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
}
and finally my fragment
public class FragmentEspecesProches extends Fragment {
public final static char SEPARATOR=',';
private RecyclerView recyclerView;
private List<Departement> departementsList = new ArrayList<>();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View view = inflater.inflate(R.layout.fragment_especes_proches, container, false);
ajouterDepartements();
recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new GridLayoutManager(this,2));
recyclerView.setAdapter(new Adapter(departementsList, getActivity()));
return view;
}
private void ajouterDepartements() {
ArrayList<String> lines = new ArrayList<>();
ArrayList<String[]> data = new ArrayList<>();
String sep = new Character(SEPARATOR).toString();
lines = UtilitaireResultat.readFile(getActivity().getResources().openRawResource(R.raw.departement));
for(String line : lines){
String[] oneData = line.split(sep);
data.add(oneData);
}
for(int i=0 ; i<data.size() ; i++){
String[] tabStr = data.get(i);
departementsList.add( new Departement( tabStr[2]+" - "+tabStr[3] ,"#drawable/"+tabStr[5] ));
}
}
}
you can implement item click listener like this
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView tvName;
public TextView tvHometown;
private Context context;
public ViewHolder(Context context, View itemView) {
super(itemView);
this.tvName = (TextView) itemView.findViewById(R.id.tvName);
this.tvHometown = (TextView) itemView.findViewById(R.id.tvHometown);
// Store the context
this.context = context;
// Attach a click listener to the entire row view
itemView.setOnClickListener(this);
}
// Handles the row being being clicked
#Override
public void onClick(View view) {
int position = getAdapterPosition(); // gets item position
// if (position != RecyclerView.NO_POSITION) { // Check if an item was deleted, but the user clicked it before the UI removed it
User user = users.get(position);
// We can access the data within the views
Toast.makeText(context, tvName.getText(), Toast.LENGTH_SHORT).show();
// }
}
}
Use onBindViewHolder to handle any interaction on your list items
#Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
Departement departement = list.get(position);
viewHolder.bind(departement, activity);
viewHolder.itemView.setOnClickListener(//your action//);
}
ItemView is the whole item; you can access your textviews or imageviews as you use it on your bind method,
You can use your bind method to apply listeners.
Handle on click of the item inside your ViewHolder constructor
like ,
public ViewHolder(View itemView) {
super(itemView);
textViewView = (TextView) itemView.findViewById(R.id.text);
imageView = (ImageView) itemView.findViewById(R.id.image);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int position=getAdapterPosition();
Toast.makeText(context, list.get(position).getText(), Toast.LENGTH_SHORT).show();
}
});
}
Create your onClickListner interface as
interface RecylerViewItemClickListner
{
void onItemClick(Department item)
}
set the listner in Adapter class
private final RecylerViewItemClickListner mOnClickListener;
public Adapter(List<Departement> list, Activity activity) {
this.list = list;
this.activity = activity;
this.mOnClickListener = activity;
}
Now in ViewHolder class
public void bind(final Departement item, final mOnClickListener listener) {
itemView.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View v) {
mOnClickListener.onItemClick(item);
}
});
}
and change onBindViewHolder as below
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.bind(items.get(position), mOnClickListener);
}
Override onItemClick(Department item) in activity
#override
onItemClick(Department item)
{
//show toast here...
}
implement OnClickListener in your ViewHolder class
public class ViewHolder extends RecyclerView.ViewHolder implements
View.OnClickListener
{
#Override
public void onClick(View v)
{
//do action
}
}
Implement below method in your ViewHolder class.
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final User currentItem = users.get(getAdapterPosition());
Toast.makeText(mContext,currentItem.getText()+" is selected!",Toast.LENGTH_SHORT).show();
}
});
I have few images in the json API, and I managed to fetch those images using volley Library. I used recyclerview with an image adapter to display image views vertically in two columns, but I want to make one image big and display it as the first image that user can click on. Also that image will be changed each interval of time. Basically, the API will do all the backend task like setting the time and telling which image to be displayed on the top of the recyclerview if not all images must have the same size and be shown in 2 columns vertically.
I have square layout class for recyclerview. I just want to know how I can do this. Even the concept will be fine.
you will have to create two view one for small item other for the header item and in onBindViewHolder have to bind those accordingly the following code is an example of a news article app and should help.
public class AdapterNewsArticlesListWithHeader extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<NewsArticles> items = new ArrayList<>();
private Context ctx;
private NewsArticles header;
private static final int TYPE_HEADER = 0;
private static final int TYPE_ITEM = 1;
private OnItemClickListener mOnItemClickListener;
public interface OnItemClickListener {
void onItemClick(View view, NewsArticles obj, int position);
}
public void setOnItemClickListener(final OnItemClickListener mItemClickListener) {
this.mOnItemClickListener = mItemClickListener;
}
// Provide a suitable constructor (depends on the kind of dataset)
public AdapterNewsArticlesListWithHeader(Context context, NewsArticles header, List<NewsArticles> items) {
this.items = items;
this.header = header;
ctx = context;
}
public class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView title;
public TextView short_content;
public TextView date;
public ImageView image;
public LinearLayout lyt_parent;
public ViewHolder(View v) {
super(v);
title = (TextView) v.findViewById(R.id.title);
short_content = (TextView) v.findViewById(R.id.short_content);
date = (TextView) v.findViewById(R.id.date);
image = (ImageView) v.findViewById(R.id.image);
lyt_parent = (LinearLayout) v.findViewById(R.id.lyt_parent);
}
}
class ViewHolderHeader extends RecyclerView.ViewHolder {
public TextView title;
public TextView date;
public ImageView image;
public LinearLayout lyt_parent;
public ViewHolderHeader(View v) {
super(v);
title = (TextView) v.findViewById(R.id.title);
date = (TextView) v.findViewById(R.id.date);
image = (ImageView) v.findViewById(R.id.image);
lyt_parent = (LinearLayout) v.findViewById(R.id.lyt_parent);
}
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_HEADER) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_header, parent, false);
return new ViewHolderHeader(v);
} else if (viewType == TYPE_ITEM) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_news, parent, false);
return new ViewHolder(v);
}
return null;
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
if (holder instanceof ViewHolderHeader) {
ViewHolderHeader vHeader = (ViewHolderHeader) holder;
vHeader.title.setText(header.getTitle());
vHeader.date.setText(header.getDate());
Picasso.with(ctx).load(header.getImage()).into(vHeader.image);
vHeader.lyt_parent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//TODO: do your thing
}
});
} else if (holder instanceof ViewHolder) {
final NewsArticles c = items.get(position);
ViewHolder vItem = (ViewHolder) holder;
vItem.title.setText(c.getTitle());
vItem.short_content.setText(c.getShort_content());
vItem.date.setText(c.getDate());
Picasso.with(ctx).load(c.getImage()).into(vItem.image);
vItem.lyt_parent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//TODO: do your thing
}
});
}
}
// need to override this method
#Override
public int getItemViewType(int position) {
if (isPositionHeader(position)) {
return TYPE_HEADER;
}
return TYPE_ITEM;
}
private boolean isPositionHeader(int position) {
return position == 0;
}
public NewsArticles getItem(int position) {
return items.get(position);
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return items.size();
}
}
In my application i have horizontal list view. On Item select I want to change that selected Item background color and it's text view color. i have figured out that part. But how to reset background color and text view color of previously selected item. here's my adapter class.
public class DateRangeListViewAdapter extends RecyclerView.Adapter<DateRangeListViewAdapter.ContentViewHolder> {
private ItemClickListener itemClickListener;
private LayoutInflater inflater;
private ArrayList<String> data;
private Context context;
private int dataType;
private int previousSelectedPosition;
private static final int DATE_TYPE = 1;
private static final int STATUS_TYPE = 2;
public DateRangeListViewAdapter(ArrayList<String> data, Context context,int dataType) {
this.data = data;
this.context = context;
this.dataType = dataType;
inflater = LayoutInflater.from(context);
previousSelectedPosition = -1;
}
public void setItemClickListener(ItemClickListener itemClickListener) {
this.itemClickListener = itemClickListener;
}
#Override
public ContentViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.custom_date_range_list_item,parent,false);
return new ContentViewHolder(view);
}
#Override
public void onBindViewHolder(ContentViewHolder holder, int position) {
String name = data.get(position);
holder.dateText.setText(name);
}
#Override
public int getItemCount() {
return data.size();
}
public class ContentViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private FrameLayout main;
private TextView dateText;
public ContentViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
main = (FrameLayout) itemView.findViewById(R.id.main_layout);
dateText = (TextView) itemView.findViewById(R.id.date_name);
}
#Override
public void onClick(View v) {
//Selected item color change
main.setBackground(ContextCompat.getDrawable(context,R.drawable.date_range_selected_item_background));
dateText.setTextColor(ContextCompat.getColor(context,R.color.colorPrimary));
if(itemClickListener!=null){
itemClickListener.onItemClick(v,this.getLayoutPosition(),dataType,getOldPosition());
}
}
}
public interface ItemClickListener{
public void onItemClick(View v, int position,int dataType,int oldPosition);
}
}
You basically want to make good use of your int flag, previousSelectedPosition, to keep track of the list item's position that was clicked, invoke notifyDataSetChanged(), and then set the flag as part of a conditional statement within onBindViewHolder() to update ViewHolder's views accordingly as they continuously get binded. Try the following changes:
ViewHolder's onClick():
#Override
public void onClick(View v) {
if (itemClickListener!=null) {
previousSelectedPosition = getAdapterPosition();
notifyDataSetChanged();
itemClickListener.onItemClick(v,this.getLayoutPosition(),dataType,getOldPosition());
}
}
RecyclerView.Adapter's onBindViewHolder():
#Override
public void onBindViewHolder(ContentViewHolder holder, int position) {
String name = data.get(position);
holder.dateText.setText(name);
if (previousSelectedPosition == position) {
main.setBackground(ContextCompat.getDrawable(context,R.drawable.date_range_selected_item_background));
dateText.setTextColor(ContextCompat.getColor(context,R.color.colorPrimary));
} else {
// TODO: Configure the FrameLayout and TextView here for initial runtime as well as back to default
}
}
... and yes, make sure to keep previousSelectedPosition initialized as -1 for the initial runtime just so the condition in onBindViewHolder() wouldn't matter until the flag updates (after a list item is clicked, that is).
Your OnClickListener does not work perfectly. You just need to implements your ViewHolder from you "ItemClickListener" interface. And add this line in onCreateViewHolder :
View view = inflater.inflate(R.layout.custom_date_range_list_item,parent,false);
ContentViewHolder cVh = ContentViewHolder(view);view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
cVh.onItemClick(v,this.getLayoutPosition(),cVh .dataType,cVh .getOldPosition());
}
});return cVh