Android Import correct Class for Item & ItemView - java

i want to use Customizing Android ListView Rows by Subclassing in my application but after wending that way i get an error to Import correct class for Item & ItemView my app support old version of android and i'm using android.support for any class.
Notify for import Item:
Notify for import ItemView:
introducing class for inport not correct and i get an error such as setItem.
How to resolve this problem and can be import correct class?
ItemAdapter class:
import java.util.List;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import ir.tsms.wsdl.ReceiveFields;
public class ItemAdapter extends ArrayAdapter<ReceiveFields> {
public ItemAdapter(Context c, List<ReceiveFields> items) {
super(c, 0, items);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ItemView itemView = (ItemView)convertView;
if (null == itemView)
itemView = ItemView.inflate(parent);
itemView.setItem(getItem(position));
return itemView;
}
}
Fragment:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ArrayList<ReceiveFields> items = new ArrayList<ReceiveFields>();
for (int i = 0; i < 100; i++) {
String url = String.format("http://www.google.com/image/%d.png", i);
String title = String.format("Item %d", i);
String description = String.format("Description of Item %d", i);
Item item = new Item(url, title, description);
items.add(item);
}
setListAdapter(new ItemAdapter(getActivity(), items));
return super.onCreateView(inflater, container, savedInstanceState);
}

As Mike M says you should be defining the Item and ItemView classes rather then trying to import them. Hence, and this is from your link, you should have two classes. ItemView looks kind of like:
public class ItemView extends RelativeLayout {
private TextView mTitleTextView;
private TextView mDescriptionTextView;
private ImageView mImageView;
public ItemView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
LayoutInflater.from(context).inflate(R.layout.item_view_children, this, true);
setupChildren();
}
public static ItemView inflate(ViewGroup parent) {
ItemView itemView = (ItemView)LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_view, parent, false);
return itemView
}
private void setupChildren() {
mTitleTextView = (TextView) findViewById(R.id.item_titleTextView);
mDescriptionTextView = (TextView) findViewById(R.id.item_descriptionTextView);
mImageView = (ImageView) findViewById(R.id.item_imageView);
}
public void setItem(Item item) {
mTitleTextView.setText(item.getTitle());
mDescriptionTextView.setText(item.getDescription());
// TODO: set up image URL
}
}
And then you would also need an Item class and to set up your layout files. I hope this helps.

The sample code for the tutorial is on github. Here are the key classes I used:
https://github.com/bignerdranch/android-listview-custom-view/tree/master/ListItemViewDemo/src/com/bignerdranch/android/listitemviewdemo
"Item" and "ItemView" are just the names I chose; you might want to use something more specific to your application's domain.
Glad you like the pattern!

Related

The Recycler View does not see the adapter elements

I have an Adapter that I pass to RecyclerView. When trying to change the text in the Recycler view, an error occurs android.content.res.Resources$NotFoundException: String resource ID #0xde. After debagging, I saw that an error occurs in the onBindViewHolder method when I change the text. At the same time, the holder object is initialized and access to the input fields is available. Please help, I'm a beginner. Thanks!
Adapter class
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ViewHolder> {
private final ArrayList<Income> incomes;
ListAdapter(ArrayList<Income> incomes) {
this.incomes = incomes;
}
#NonNull
#Override
public ListAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ListAdapter.ViewHolder holder, int position) {
Income income = incomes.get(position);
holder.summaView.setText(income.getSumma());
holder.typeView.setText(income.getType());
holder.dataView.setText(income.getData());
}
#Override
public int getItemCount() {
return incomes.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
public TextView typeView, dataView, summaView;
ViewHolder(View view){
super(view);
summaView = view.findViewById(R.id.SumListItem);
typeView = view.findViewById(R.id.TypeListItem);
dataView = view.findViewById(R.id.DateListItem);
}
}
}
Initialize recyclerview
#Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState
) {
View view = inflater.inflate(R.layout.fragment_incomes_list, container, false);
RecyclerView = recyclerView = view.findViewById(R.id.list_INC);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(view.getContext()));
recyclerView.setAdapter(new ListAdapter(incomes));
return view;
}
Error:
enter image description here
enter image description here
note that TextView have multiple setText method implementation, e.g.
setText(CharSequence) - may takeString and will show it
setText(int) - takes an int and will treat it like resource id (strings.xml pointer)
when you call setText(someIntValue) then TextView will try to resolve such number as a resources refence, which most probably doesn't exists (thus Resources$NotFoundException)
so you have to convert by own your int to String, by e.g. ""+someIntValue or String.valueOf(someIntValue)
String summaAsString = ""+income.getSumma();
holder.summaView.setText(summaAsString);
PS. don't EVER post text as screenshot/picture, it's hard to copy it...

Why is the delete button on my list view not working [duplicate]

This question already has answers here:
Delete button on my listview is not working as it is supposed to
(2 answers)
Closed 1 year ago.
I want to implement this delete button on my list view... I have tried to set the tag of my button as the position of the list item, and then I try to remove it using the remove method, but it just doesn't work. What might the issue here? Please note that I am fairly new at this, so I'm sorry if my code isn't good.
this is the code for my adapter:
// full subtask adapter code
package com.example.taskmasterv3;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.ArrayList;
public class SubtaskAdapter extends ArrayAdapter<subtask> {
private final Context context;
private ArrayList<subtask> values;
public SubtaskAdapter(Context context, ArrayList<subtask> list) {
//since your are using custom view,pass zero and inflate the custom view by overriding getview
super(context, 0 , list);
this.context = context;
this.values = list;
}
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
//check if its null, if so inflate it, else simply reuse it
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.subtask_item, parent, false);
}
//use convertView to refer the childviews to populate it with data
TextView tvSubtaskName = convertView.findViewById(R.id.tvSubtaskName);
ImageView ivPri = convertView.findViewById(R.id.ivPri);
ImageView ivTime = convertView.findViewById(R.id.ivTime);
ImageView ivDelete = convertView.findViewById(R.id.ivDelete);
ivDelete.setTag(position);
tvSubtaskName.setText(values.get(position).getSubtaskName());
if (values.get(position).isPriHigh()) {
ivPri.setImageResource(R.drawable.priority_high);
} else if (values.get(position).isPriMed()) {
ivPri.setImageResource(R.drawable.priority_med);
} else if (values.get(position).isPriLow()) {
ivPri.setImageResource(R.drawable.priority_low);
}
if (values.get(position).isTimeMore()) {
ivTime.setImageResource(R.drawable.time_symbol_more);
} else if (values.get(position).isTimeMed()) {
ivTime.setImageResource(R.drawable.time_symbol_med);
} else if (values.get(position).isTimeLess()) {
ivTime.setImageResource(R.drawable.time_symbol_less);
}
// Delete button for subtasks (NOT WORKING)
ivDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
values.remove(ivDelete.getTag());
notifyDataSetChanged();
}
});
//return the view you inflated
return convertView;
}
//to keep adding the new subtasks try the following
public void addANewSubTask(subtask newSubTask){
ArrayList<subtask> newvalues = new ArrayList<>(this.values);
newvalues.add(newSubTask);
this.values = newvalues;
notifyDataSetChanged();
}
}
I have done in this way. Maybe it could help you. Anyway, try using debugger in order to check if it is called when pressed
public class ListNoteAdapter extends BaseAdapter implements ListAdapter {
private ArrayList<Nota> arrayList;
private Context context;
public ListNoteAdapter(ArrayList<Nota> arrayList, Context context) {
this.arrayList = arrayList;
this.context = context;
}
#Override
public int getCount() {
return arrayList.size();
}
#Override
public Object getItem(int position) {
return arrayList.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if(view == null){
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_view_with_button, parent, false);
}
TextView textView = view.findViewById(R.id.list_item);
textView.setText(arrayList.get(position).toString());
//When user click on a text view, text will be saved into clipboard
textView.setOnClickListener( v -> {
ClipboardManager clipboardManager = (ClipboardManager)context.getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clipData = ClipData.newPlainText("Note clipboard", textView.getText().toString());
clipboardManager.setPrimaryClip(clipData);
Toast.makeText(context, "Testo copiato negli appunti", Toast.LENGTH_SHORT).show();
});
ImageButton deleteButton = view.findViewById(R.id.deleteNote);
deleteButton.setOnClickListener( v -> {
LayoutInflater layoutInflater = (LayoutInflater)parent.getContext().getSystemService(parent.getContext().LAYOUT_INFLATER_SERVICE);
View popupView = layoutInflater.inflate(R.layout.delete_popup_window, parent, false);
Button decline = popupView.findViewById(R.id.deleteDeclineButton);
/**
* In order to allow the user to delete any note voluntarily,
* a confirming popup window will appear
*/
PopupWindow popupWindow = new PopupWindow(popupView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true);
Button agreed = popupView.findViewById(R.id.deleteAgreeButton);
agreed.setOnClickListener(v1 ->{
File file = new File(context.getFilesDir(),
arrayList.get(position).date + "#" + arrayList.get(position).time + ".txt");
if(file.exists())
file.delete();
arrayList.remove(position);
popupWindow.dismiss();
//Update the list view to show the new note without needing to restart the application
this.notifyDataSetChanged();
});
decline.setOnClickListener(vDecline -> {
popupWindow.dismiss();
});
popupWindow.showAtLocation(popupView, Gravity.CENTER, 0, 0);
});
return view;
}
}
Why don't you delete by position directly
values.remove(position);

I have a Recycler View, onRun will display, but upon a button click it will be empty, I want to set a default recycler view

I currently have a recycler view that works off Latitude and Longitude within Android studio. On load due to using an emulator i pass a default location, this loads areas around the location within a map. I also have a spinner which allows you to change area and display markers on a map on screen. However the problem is when the Location which in my case is the current location (set to default emulator location Google Pixel San Francisco?) is used, the recycler view shows as empty, i want to edit my recycler view within my Adapter class so that IF the view is empty set the text to "No places around you" if code needed please ask.
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
QuietPlace quietPlace = mQuietPlace.get(position);
if (mQuietPlace.size() > 0){
TextView textView = holder.titleTextView;
textView.setText(quietPlace.getName());
TextView textView2 = holder.noiseTextView;
textView2.setText(quietPlace.getNoise());
TextView textView3 = holder.distanceTextView;
textView3.setText(String.valueOf(quietPlace.getDistance()));
}
else {
TextView textViewEmpty = holder.titleTextView;
textViewEmpty.setText("No Quiet Places near your location");
TextView textViewEmpty2 = holder.noiseTextView;
textViewEmpty2.setText(" ");
TextView textViewEmpty3 = holder.distanceTextView;
textViewEmpty3.setText(" ");
}
}
Edit:
package com.example.myapplication;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class QuietPlaceAdapter extends RecyclerView.Adapter<QuietPlaceAdapter.ViewHolder> {
private List<QuietPlace> mQuietPlace;
public QuietPlaceAdapter(List<QuietPlace> quietPlaces)
{
mQuietPlace = quietPlaces;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View quietPlaceView = inflater.inflate(R.layout.recycler_view, parent, false);
ViewHolder viewHolder = new ViewHolder(quietPlaceView);
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
QuietPlace quietPlace = mQuietPlace.get(position);
TextView textView = holder.titleTextView;
textView.setText(quietPlace.getName());
TextView textView2 = holder.noiseTextView;
textView2.setText(quietPlace.getNoise());
TextView textView3 = holder.distanceTextView;
textView3.setText(String.valueOf(quietPlace.getDistance()));
}
#Override
public int getItemCount() {
return mQuietPlace.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView titleTextView;
public TextView noiseTextView;
public TextView distanceTextView;
public ViewHolder(View itemView) {
super(itemView);
titleTextView = (TextView) itemView.findViewById(R.id.quietPlaceTitle);
noiseTextView = (TextView) itemView.findViewById(R.id.quietPlaceNoise);
distanceTextView = (TextView) itemView.findViewById(R.id.quietPlaceDistance);
}
}
}
Don't pass the list in constructor if it is dynamic.
Add this function in your adapter
public void setPanelList(List<QuietPlace> quietPlaces){
mQuietPlace = quietPlaces;
notifyDataSetChanged();
}
In activity, setPanelList(quietPlaces) when your quietPlaces changed.
quietPlaceAdapter.setPanelList(quietPlaces)
Hope this helps.

How to get a View from xml file using LayoutInflater in a java class not extending Activity

I have a java class where I am displaying a dialog using an XML layout file. I want to set the text/contents of the layout dynamically.
To achieve this I am writing a method like this :
private void setContentMessage(String theMessage)
{
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_content, null, false);
TextView titleMessage = (TextView) contentView.findViewById(R.id.title_message);
titleMessage.setText(theMessage);
}
So here inside the inflate method I am using null because I don't know what to use.
Generally, we use ViewGroup object as the second argument in inflate method but I don't know how to create a ViewGroup inside a java class not extending Activity.
The function that I have written above is making not change inside the dialog layout. So please tell how can I inflate a layout in a java class.
AmitSmartDialog.java
package com.amitupadhyay.touchme.utility;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import android.widget.Toast;
import com.amitupadhyay.touchme.R;
import com.orhanobut.dialogplus.DialogPlus;
import com.orhanobut.dialogplus.Holder;
import com.orhanobut.dialogplus.OnCancelListener;
import com.orhanobut.dialogplus.OnClickListener;
import com.orhanobut.dialogplus.OnDismissListener;
import com.orhanobut.dialogplus.OnItemClickListener;
import com.orhanobut.dialogplus.ViewHolder;
/**
* Created by aupadhyay on 12/9/16.
*/
public class AmitSmartDialog {
Context context;
public AmitSmartDialog(Context context) {
this.context = context;
}
public void showDialog(int holderId, int gravity, boolean showHeader, boolean showFooter, boolean expanded, String message) {
setContentMessage(message);
Holder holder;
holder = new ViewHolder(R.layout.dialog_content);
OnClickListener clickListener = new OnClickListener() {
#Override
public void onClick(DialogPlus dialog, View view) {
switch (view.getId()) {
case R.id.like_it_button:
Toast.makeText(context, "We're glad that you like it", Toast.LENGTH_LONG).show();
break;
case R.id.love_it_button:
Toast.makeText(context, "We're glad that you love it", Toast.LENGTH_LONG).show();
break;
}
dialog.dismiss();
}
};
OnItemClickListener itemClickListener = new OnItemClickListener() {
#Override
public void onItemClick(DialogPlus dialog, Object item, View view, int position) {
}
};
OnDismissListener dismissListener = new OnDismissListener() {
#Override
public void onDismiss(DialogPlus dialog) {
}
};
OnCancelListener cancelListener = new OnCancelListener() {
#Override
public void onCancel(DialogPlus dialog) {
}
};
showCompleteDialog(holder, gravity, new BaseAdapter() {
#Override
public int getCount() {
return 0;
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
return null;
}
}, clickListener, itemClickListener, dismissListener, cancelListener,
expanded);
}
private void showCompleteDialog(Holder holder, int gravity, BaseAdapter adapter,
OnClickListener clickListener, OnItemClickListener itemClickListener,
OnDismissListener dismissListener, OnCancelListener cancelListener,
boolean expanded) {
final DialogPlus dialog = DialogPlus.newDialog(context)
.setContentHolder(holder)
.setHeader(R.layout.dialog_header)
.setCancelable(false)
.setGravity(gravity)
.setAdapter(adapter)
.setOnClickListener(clickListener)
.setOnItemClickListener(new OnItemClickListener() {
#Override public void onItemClick(DialogPlus dialog, Object item, View view, int position) {
}
})
.setOnDismissListener(dismissListener)
.setExpanded(expanded)
.setContentHeight(ViewGroup.LayoutParams.WRAP_CONTENT)
.setOnCancelListener(cancelListener)
.setOverlayBackgroundResource(android.R.color.transparent)
.create();
dialog.show();
}
private void setContentMessage(String theMessage)
{
Toast.makeText(context, "HI BRO", Toast.LENGTH_SHORT).show();
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_content, null, false);
TextView titleMessage = (TextView) contentView.findViewById(R.id.title_message);
titleMessage.setText(theMessage);
}
}
Use this way :
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View contentView = inflater.inflate(R.layout.dialog_content, null,false);
Or
LayoutInflater inflater = LayoutInflater.from(getApplicationContext);
View contentView = inflater.inflate(R.layout.dialog_content, null,false);
UpDate :
Do some Change like this way
setContentMessage(message); pass context as parameter.
so change like this
setContentMessage(message, context);
and change this also.
private void setContentMessage(String theMessage,Context context)
{
View contentView = contxet.getLayoutInflater().inflate(R.layout.dialog_content, null);
TextView titleMessage = (TextView) contentView.findViewById(R.id.title_message);
titleMessage.setText(theMessage);
}
Pass context in an argument of that method then use this
"(LayoutInflater)
mActivity.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);"
private void setContentMessage(String theMessage, Activity mActivity)
{
LayoutInflater mInflater = (LayoutInflater)
mActivity.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
View contentView = mInflater.inflate(R.layout.dialog_content, null, false);
TextView titleMessage = (TextView) contentView.findViewById(R.id.title_message);
titleMessage.setText(theMessage);
}
From what I'm understanding from your code, you are creating a dialog with a custom view, and then you want to set a message to some textview inside that dialog.
I see that you also use a holder, so instead of calling setContentMessage(message), which is redundant, you could something like this
Holder holder;
holder = new ViewHolder(R.layout.dialog_content);
holder.titleMessage = message
Inside the Holder implementation you should have a field that points to the title textView (that's how a holder pattern should be anyway).

GridviewLayoutManager with headers

I am working on an app
I have implemented a working recycler view that receives a jsonarray, passes the data to a string array.
I now want to add section headers to the layout manager.
I have read two schools of thought on this:
- Change the spansize of the view to match the total columns of the grid
- create a custom adapter that loads a different view if the item is a section header.
Im not sure which way to go with this and its starting to confuse me
I have a list of data in an array which includes both headers and grid data (myDataset), i have also created another array with the mapping for the dataset in (myDatamap). In myDatamap i have a list of field types (1 for header and 0 for griddata. I was hoping to pass both arrays to the adaptor and for it decide if its a header or a griditem and then load the appropriate view.
I am leaning more towards loading a different view for the header items, allowing for me to customise the layout of the header easier.
Here is my adaptor code
package com.example.alex.recyclerview2;
import java.util.ArrayList;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private ArrayList<String> mDataset;
private ArrayList<Integer> mDatamap;
private Context context;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView txtHeader;
public TextView txtFooter;
public ImageView imgImage;
public ViewHolder(View v) {
super(v);
txtHeader = (TextView) v.findViewById(R.id.firstLine);
txtFooter = (TextView) v.findViewById(R.id.secondLine);
imgImage = (ImageView) v.findViewById(R.id.icon);
}
}
public void add(int position, String item) {
mDataset.add(position, item);
notifyItemInserted(position);
}
public void remove(String item) {
int position = mDataset.indexOf(item);
mDataset.remove(position);
notifyItemRemoved(position);
}
// Provide a suitable constructor (depends on the kind of dataset)
public MyAdapter(ArrayList<String> myDataset, ArrayList<Integer> myDatamap) {mDataset = myDataset;myDatamap=mDatamap; }
// Create new views (invoked by the layout manager)
#Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.sub_layout, parent, false);
context = v.getContext();
// set the view's size, margins, paddings and layout parameters
ViewHolder vh = new ViewHolder(v);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
final String name = mDataset.get(position);
Picasso.with(context).load("http://www.500kgiveaway.co.uk/" + name).resize(200,200).into(holder.imgImage);
// holder.txtHeader.setText(mDataset.get(position));
holder.txtHeader.setText(name);
holder.txtHeader.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
remove(name);
}
});
holder.txtFooter.setText("Footer: " + mDataset.get(position));
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return mDataset.size();
}
}
ive not had much interest in this post but here is the answer
i hope this help someone else
What i have done is implemented a custom view adaptor to manage the item types
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
public class ElementsAdapter extends RecyclerView.Adapter<ElementsAdapter.ViewHolder> {
private ArrayList<String> mDataset;
private ArrayList<Integer> mDatamap;
public Context context;
private static final int VIEW_HEADER = 0;
private static final int VIEW_NORMAL = 1;
private View headerView;
private int datasetSize;
public class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView txtHeader;
public TextView txtFooter;
public ImageView imgImage;
//header
public TextView headertext;
public ViewHolder(View v, int viewType) {
super(v);
switch (viewType){
case 1:
txtHeader = (TextView) v.findViewById(R.id.firstLine);
txtFooter = (TextView) v.findViewById(R.id.secondLine);
imgImage = (ImageView) v.findViewById(R.id.icon);
case 0:
headertext = (TextView) v.findViewById(R.id.headertext);
}
}
}
public ElementsAdapter(ArrayList<String> myDataset, ArrayList<Integer> myDatamap) {
mDataset = myDataset;
mDatamap = myDatamap;
}
#Override
public int getItemViewType(int position) {
return isHeader(position) == 1 ? VIEW_HEADER : VIEW_NORMAL;
}
#Override
public int getItemCount() {
return mDataset.size();
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == VIEW_HEADER) {
// create a new view
View sub_view = LayoutInflater.from(parent.getContext()).inflate(R.layout.header, parent, false);
Context context = sub_view.getContext();
// set the view's size, margins, paddings and layout parameters
ViewHolder vh = new ViewHolder(sub_view,viewType);
return vh;
// return new HeaderViewHolder(headerView);
} else {
// create a new view
View sub_view = LayoutInflater.from(parent.getContext()).inflate(R.layout.sub_layout, parent, false);
context = sub_view.getContext();
// set the view's size, margins, paddings and layout parameters
ViewHolder vh = new ViewHolder(sub_view, viewType);
return vh;
}
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
if (isHeader(position) == 1) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
final String name = mDataset.get(position);
// holder.txtHeader.setText(mDataset.get(position));
viewHolder.headertext.setText(name);
} else {
// - get element from your dataset at this position
// - replace the contents of the view with that element
final String name = mDataset.get(position);
Picasso.with(context).load("http://www.500kgiveaway.co.uk/"+name).resize(200,200).into(viewHolder.imgImage);
// holder.txtHeader.setText(mDataset.get(position));
viewHolder.txtHeader.setText(name);
viewHolder.txtHeader.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick (View v){
//remove(name);
}
}
);
viewHolder.txtFooter.setText("Footer: "+mDataset.get(position));
}
//ViewHolder holder = (ViewHolder) viewHolder;
//holder.textView.setText("Position " + (position - 1));
}
public int isHeader(int position) {
return mDatamap.get(position) ==1 ? 1:0;}
}
Why don't you use both solutions? If you set the span size you can easily set a textview or whatever you want the header to be.
gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
#Override
public int getSpanSize(int position) {
return adapter.isHeader(position) ? gridLayoutManager.getSpanCount() : 1;
}
});
Then in the adapter have a general class Item that says if the item is a header and has some information about the real item that should be shown, in my case since I have image paths for showing images and titles for headers I just use a attribute text but you can use something like int realPositionInTheirLists since headers titles and images paths are in two separate lists:
private static class Item {
public boolean isHeader;
public String text;
public Item(String text, boolean isHeader) {
this.isHeader = isHeader;
this.text = text;
}
}
Then you have something like this on the methods that tell which type of item it is:
#Override
public int getItemViewType(int position) {
return mItems.get(position).isHeader ? VIEW_TYPE_HEADER : VIEW_TYPE_CONTENT;
}
public boolean isHeader(int position) {
return mItems.get(position).isHeader;
}
Then finally on the two methods that inflate the view and bind the data you inflate the view that you want depending on whether it is a header or not and bind the data using the Item class:
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
if (viewType == VIEW_TYPE_HEADER) {
view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.grid_header, parent, false);
} else {
view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.grid_item, parent, false);
}
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
final Item item = mItems.get(position);
holder.bindItem(item, position);
}
Being the holder.bindItem a method of the ViewHolder class. There you can choose however you want to separate both views.

Categories

Resources