I am having a problem with my GridView wherein the images loads in different places when scrolling. I know this has something to do with recycling but as I am new to Android, I have no idea about this.
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
final Listing listing = getItem(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.listing_items, parent, false);
}
final ImageView imageView = (ImageView) convertView.findViewById(R.id.imageView);
FirebaseStorage.getInstance().getReference().child(listing.authorUid).child(listing.adId).child(listing.images.get(0)).getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
try {
GlideApp.with(getContext())
.load(new URL(uri.toString()))
.into(imageView);
} catch(Exception e) {
e.printStackTrace();
}
}
});
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getContext(), ItemInfoActivity.class);
intent.putExtra("title", listing.title);
intent.putExtra("location", listing.city);
intent.putExtra("price", listing.price);
intent.putExtra("desc", listing.description);
intent.putExtra("category", listing.category);
intent.putExtra("author", listing.authorUid);
intent.putExtra("adId", listing.adId);
intent.putExtra("authorId", listing.authorUid);
startActivity(intent);
}
});
TextView price = (TextView)convertView.findViewById(R.id.price_txt);
TextView title = (TextView)convertView.findViewById(R.id.title_txt);
title.setText(listing.title);
price.setText(listing.price +"DH");
return convertView;
}
Please advise on what to do.
import android.content.Context;
import android.content.Intent;
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 java.util.ArrayList;
public class CustomAdapter extends RecyclerView.Adapter {
ArrayList personNames;
ArrayList personImages;
Context context;
public CustomAdapter(Context context, ArrayList personNames, ArrayList personImages) {
this.context = context;
this.personNames = personNames;
this.personImages = personImages;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// infalte the item Layout
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.rowlayout, parent, false);
// set the view's size, margins, paddings and layout parameters
MyViewHolder vh = new MyViewHolder(v); // pass the view to View Holder
return vh;
}
#Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
// set the data in items
holder.name.setText(personNames.get(position));
holder.image.setImageResource(personImages.get(position));
// implement setOnClickListener event on item view.
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// open another activity on item click
Intent intent = new Intent(context, SecondActivity.class);
intent.putExtra("image", personImages.get(position)); // put image data in Intent
context.startActivity(intent); // start Intent
}
});
}
#Override
public int getItemCount() {
return personNames.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
// init the item view's
TextView name;
ImageView image;
public MyViewHolder(View itemView) {
super(itemView);
// get the reference of item view's
name = (TextView) itemView.findViewById(R.id.name);
image = (ImageView) itemView.findViewById(R.id.image);
}
}
}
Use this adapter structure.
import android.content.Context;
import android.content.Intent;
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 java.util.ArrayList;
public class CustomAdapter extends RecyclerView.Adapter {
ArrayList personNames;
ArrayList personImages;
Context context;
public CustomAdapter(Context context, ArrayList personNames, ArrayList personImages) {
this.context = context;
this.personNames = personNames;
this.personImages = personImages;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// infalte the item Layout
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.rowlayout, parent, false);
// set the view's size, margins, paddings and layout parameters
MyViewHolder vh = new MyViewHolder(v); // pass the view to View Holder
return vh;
}
#Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
// set the data in items
holder.name.setText(personNames.get(position));
holder.image.setImageResource(personImages.get(position));
// add your firebase code here
// implement setOnClickListener event on item view.
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// open another activity on item click
Intent intent = new Intent(context, SecondActivity.class);
intent.putExtra("image", personImages.get(position)); // put image data in Intent
context.startActivity(intent); // start Intent
}
});
}
#Override
public int getItemCount() {
return personNames.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
// init the item view's
TextView name;
ImageView image;
public MyViewHolder(View itemView) {
super(itemView);
// get the reference of item view's
name = (TextView) itemView.findViewById(R.id.name);
image = (ImageView) itemView.findViewById(R.id.image);
}
}
}
Here is the updated answer of above answer.
if you are using recyclerview you can not override getView() method.
i would suggest you to use recyclerview.
Related
I tried to implement OnItemClickListener in Fragment with RecycleView Adapter, but my code seems not to work well, OnItemClickListener keeps turning red when I try to change it to getContext().
I've tried to find many ways to get it done, but that makes me find another error in my code.
.
your help will make my day brighter,
public class MountainFragment extends Fragment {
private final int LOCATION_SIZE = 10;
private final int LOCATION_TYPE = 1;
public MountainFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.word_list_activity, container, false);
String name, imageName, address;
Drawable image;
int resourceId, imageId;
final ArrayList<WorldDataModel> mountainArrays = new ArrayList<WorldDataModel>();
for (int n = 1; n <= LOCATION_SIZE; n++) {
//get Location Name
resourceId = getResources().getIdentifier("location_name_" + LOCATION_TYPE
+ "_" + n, "string", getActivity().getPackageName());
name = getResources().getString(resourceId);
//get address
resourceId = getResources().getIdentifier("location_address_" + LOCATION_TYPE
+ "_" + n, "string", getActivity().getPackageName());
address = getResources().getString(resourceId);
//get image thumbnail
resourceId = getResources().getIdentifier("location_thumbnail_" + LOCATION_TYPE
+ "_" + n, "string", getActivity().getPackageName());
imageName = getResources().getString(resourceId);
imageId = getResources().getIdentifier(imageName, "drawable", getActivity().getPackageName());
image = getResources().getDrawable(imageId);
//add new data to list
mountainArrays.add(new WorldDataModel(name, address, image));
}
// using simple recycle view
RecyclerView recyclerView = (RecyclerView) rootView.findViewById(R.id.word_list_activity);
recyclerView.setLayoutManager(new LinearLayoutManager(this.getContext()));
RecycleViewWorldAdapter adapter = new RecycleViewWorldAdapter(mountainArrays);
recyclerView.setAdapter(adapter);
//on list item click
recyclerView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
WorldDataModel worldDataModel = mountainArrays.get(position);
Intent intent = new Intent(getActivity(), DetailsActivity.class);
intent.putExtra("category", LOCATION_TYPE);
intent.putExtra("location", position + 1);
getActivity().startActivity(intent);
}
});
// Inflate the layout for this fragment
return rootView;
}
and here's my adapter class
package com.example.mytourguideapp;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
public class RecycleViewWorldAdapter extends RecyclerView.Adapter<RecycleViewWorldAdapter.MyViewHolder> {
private ArrayList<WorldDataModel> worldDataModelArrayList;
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView textViewLocationName, textViewPlacesName;
public ImageView imageOnCard;
public MyViewHolder(View itemView) {
super(itemView);
textViewLocationName = (TextView) itemView.findViewById(R.id.location_name);
textViewPlacesName = (TextView) itemView.findViewById(R.id.places_name);
imageOnCard = (ImageView) itemView.findViewById(R.id.image_on_cardview);
}
}
public RecycleViewWorldAdapter(ArrayList<WorldDataModel> worldDataModelArrayList) {
this.worldDataModelArrayList = worldDataModelArrayList;
}
#Override
public MyViewHolder onCreateViewHolder( ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item_layout, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(RecycleViewWorldAdapter.MyViewHolder holder, int position) {
WorldDataModel worldDataModel = worldDataModelArrayList.get(position);
holder.textViewPlacesName.setText(worldDataModel.getName());
holder.textViewLocationName.setText(worldDataModel.getAddress());
holder.imageOnCard.setImageDrawable(worldDataModel.getImageThumbnail());
}
#Override
public int getItemCount() {
return worldDataModelArrayList.size();
}
}
You can send the callback from your Adapter class to your fragment/activity.
First create a interface class
public interface OnItemClickListener {
void onItemClick(WorldDataModel item,int position);
}
Next modify your Adapter class , in your case RecycleViewWorldAdapter
i) Send listener as a parameter in your constructor
private final OnItemClickListener listener;
public RecycleViewWorldAdapter(ArrayList<WorldDataModel> worldDataModelArrayList, OnItemClickListener listener) {
this.worldDataModelArrayList = worldDataModelArrayList;
this.listener = listener;
}
ii) Set onCLick listener on some view in your ViewHolder class
public MyViewHolder(View itemView) {
super(itemView);
textViewLocationName = (TextView) itemView.findViewById(R.id.location_name);
textViewPlacesName = (TextView) itemView.findViewById(R.id.places_name);
imageOnCard = (ImageView) itemView.findViewById(R.id.image_on_cardview);
// change your listener on any other view if you want
imageOnCard..setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View v) {
listener.onItemClick(worldDataModelArrayList.get(getAdapterPosition()),getAdapterPosition());
}
});
}
Now modify your Activity/Fragment class to listen to your interface callback , in your case MountainFragment in onCreateView
// using simple recycle view
RecyclerView recyclerView = (RecyclerView) rootView.findViewById(R.id.word_list_activity);
recyclerView.setLayoutManager(new LinearLayoutManager(this.getContext()));
RecycleViewWorldAdapter adapter = new RecycleViewWorldAdapter(mountainArrays,new RecycleViewWorldAdapter.OnItemClickListener() {
#Override public void onItemClick(WorldDataModel item, int position) {
// implement click listener as per your requirement
WorldDataModel worldDataModel = item;
Intent intent = new Intent(getActivity(), DetailsActivity.class);
intent.putExtra("category", LOCATION_TYPE);
intent.putExtra("location", position + 1);
getActivity().startActivity(intent);
});
recyclerView.setAdapter(adapter);
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 want to add a footer to my recycler view. I have attached the custom adapter code below. How can I do this? I want the button to fill the recycler view with new items. I can do the button functioning on my own. I'm only facing the problem adding the footer.
I want something like the image attached below:
package com.example.myapplication.Adapter;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.example.myapplication.Interface.ItemClickListener;
import com.example.myapplication.Model.RSSObject;
import com.example.myapplication.R;
class FeedViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener{
public TextView textTitle,txtDate,textContent;
private ItemClickListener itemClickListener;
public FeedViewHolder(View itemView) {
super(itemView);
textTitle = (TextView) itemView.findViewById(R.id.textTitle);
txtDate = itemView.findViewById(R.id.textPubDate);
textContent = itemView.findViewById(R.id.textContent);
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
}
public FeedViewHolder(View itemView, ItemClickListener itemClickListener) {
super(itemView);
this.itemClickListener = itemClickListener;
}
#Override
public void onClick(View v) {
itemClickListener.onClick(v, getAdapterPosition(), false);
}
#Override
public boolean onLongClick(View v) {
itemClickListener.onClick(v, getAdapterPosition(), true);
return true;
}
}
public class FeedAdapter extends RecyclerView.Adapter<FeedViewHolder> {
private RSSObject.RssObject rssObject;
private Context mContext;
private LayoutInflater layoutInflater;
public FeedAdapter(RSSObject.RssObject rssObject, Context mContext) {
this.rssObject = rssObject;
this.mContext = mContext;
layoutInflater = layoutInflater.from(mContext);
}
#Override
public int getItemViewType(int position) {
return super.getItemViewType(position);
}
#Override
public FeedViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final View itemView = layoutInflater.inflate(R.layout.row,parent,false);
return new FeedViewHolder(itemView);
}
#Override
public void onBindViewHolder(final FeedViewHolder holder, final int position) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String url = rssObject.getItems().get(holder.getAdapterPosition()).getLink();
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
v.getContext().startActivity(i);
}
});
String title = rssObject.getItems().get(position).getTitle();
title = title.replace("&","");
holder.textTitle.setText(title);
String description = rssObject.getItems().get(position).getDescription();
description = android.text.Html.fromHtml(description).toString();
holder.textContent.setText(description);
holder.txtDate.setText(rssObject.getItems().get(position).getPubDate());
}
#Override
public int getItemCount() {
return rssObject.items.size();
}
}
There are two ways:
If you want a fixed view put under RecyclerView in your xml file a Relative Layout (or orher) with the button inside
Or if you want the button as an element of the list you should add a view with the button ad the last position of your view
If you wish to add a footer, you need to specify it as another type of view.
In your adapter code you should add logic for creation of another holder for the footer.
Please see the following Kotlin example:
const val REGULAR_VIEW_TYPE = 0
const val FOOTER_VIEW_TYPE = 1
class FooterExampleAdapter(
private val data: List<String>
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
when (viewType) { // Use 'when' to create the correct holder for any position
REGULAR_VIEW_TYPE -> RegularViewHolder(parent.inflateView(R.layout.regular_layout))
FOOTER_VIEW_TYPE -> FooterViewHolder(parent.inflateView(R.layout.footer_layout))
}
// Handle binding by checking holder type
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is RegularViewHolder) holder.bind(data[position])
else if (holder is FooterViewHolder) holder.bind()
}
override fun getItemCount() = data.size + 1 // We need the extra 1 for the footer to be counted
// Here is where we specify which view type should be presented at position
override fun getItemViewType(position: Int) =
if (position == data.size) FOOTER_VIEW_TYPE else REGULAR_VIEW_TYPE
}
class RegularViewHolder(v: View) : RecyclerView.ViewHolder(v) {
fun bind(string: String) {}
}
class FooterViewHolder(v: View) : RecyclerView.ViewHolder(v) {
fun bind() {}
}
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).
when I dynamic remove an item, or when I refresh the adapter(swipe to fresh) i get these erros:
recyclerview onclicklistener java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
Really can't figure out why this is happening, Really Appreciate any feed back.
MainActivity:
adapter.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(View view, int position) {
GroupModel selectedList = mGroupModels.get(position);
if (selectedList != null) {
Log.d(TAG, "setAdpterListner > view.getId: " + view.getId() +
" | P: " + position +
" | data ID: " + selectedList.getGroupName()
//" | viewID: " + viewID
);
Intent intent = new Intent(this, DetailsActivity.class);
String listId = selectedList.getGroupID();
String listName = selectedList.getGroupName();
intent.putExtra(Constant.KEY_LIST_ID, listId);
intent.putExtra(Constant.KEY_LIST_NAME, listName);
startActivity(intent);
}
}
});
Adapter:
public class GroupListAdapter extends RecyclerView.Adapter<GroupListAdapter.StatusViewHolder> {
Context context;
private List<GroupModel> mGroupModels;
private static OnItemClickListener listener;
public GroupListAdapter(Context context, List<GroupModel> groupList) {
this.context = context;
this.mGroupModels = groupList;
}
public void setOnItemClickListener(OnItemClickListener listener) {
GroupListAdapter.listener = listener;
}
#Override
public StatusViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_group_list, parent, false);
return new StatusViewHolder(view);
}
#Override
public void onBindViewHolder(StatusViewHolder holder, int position) {
final GroupModel data = mGroupModels.get(position);
holder.text_view_list_name.setText(data.getGroupName());
}//end onBindViewHolder
#Override
public int getItemCount() {
return mGroupModels.size();
}
public class StatusViewHolder extends RecyclerView.ViewHolder {
public TextView text_view_list_name;
public TextView created_by;
public StatusViewHolder(final View itemView) {
super(itemView);
text_view_list_name = (TextView) itemView.findViewById(R.id.text_view_list_name);
created_by = (TextView) itemView.findViewById(R.id.created_by);
// Setup the click listener
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (listener != null)
listener.onItemClick(itemView, getLayoutPosition());
}
});
}
}//end StatusViewHolder
}//end GroupListAdapter
UPDATE:
I taken into consideration Yurii Tsap Feedback. I check the code again. I think the problem is somewhere below:
Whenever I swipe to Fresh, and If i click on the list straight way, the app Crash with the error from above.
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
// Refresh items
mRecyclerView.invalidate();
adapter = null;
initGetGroupList();
mSwipeRefreshLayout.setRefreshing(false);
}
});
In the API call
...
GroupModel groupModel = new GroupModel(groupID, groupName, groupCreatedBy);
mGroupModels.add(groupModel);
}
updateUI(true);
if (adapter == null) {
adapter = new GroupListAdapter(MainActivity.this, mGroupModels);
mRecyclerView.setAdapter(adapter);
setAdapterListener(adapter);
}
The problem is definitely not in the static listener. And also the listener is just an interface callback(related to the comment above) not a AdapterView.OnItemClickListener(). I think the problem is somewhere behind this code, maybe you are clearing the item list somewhere else or something like that?
And also as for me in your case it's better to use getAdapterPosition() instead of getLayoutPosition().
As mentioned in docs :
If LayoutManager needs to call an external method that requires the adapter position of the item, it can use getAdapterPosition() or RecyclerView.Recycler.convertPreLayoutPositionToPostLayout(int).
Make OnItemClickListener non static .Like
private OnItemClickListener listener;
your code have alot of problem
i will explain my way to handle recycle view
very simple adapter
package com.pentavalue.ongo.transportway.adapter;
import android.app.Activity;
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.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import com.pentavalue.ongo.R;
import com.pentavalue.ongo.Utilts.ImageLoaderHelper;
import com.pentavalue.ongo.register.model.Vechiles;
import com.pentavalue.ongo.widget.ArabicTextView;
import java.util.ArrayList;
/**
* Created by hamada on 19/09/2015.
*/
public class TransportTypeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public LayoutInflater inflater = null;
Activity activity;
ArrayList<Vechiles> vechileList;
ImageLoaderHelper imageLoaderHelper;
public TransportTypeAdapter(Activity activity, ArrayList<Vechiles> vechileList) {
this.activity = activity;
this.vechileList = vechileList;
imageLoaderHelper = new ImageLoaderHelper(activity, null);
inflater = LayoutInflater.from(activity);
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View vi = inflater.inflate(R.layout.single_transport_item, parent, false);
RecyclerView.ViewHolder vh = new VechileListHolder(vi);
return vh;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int pos) {
VechileListHolder mHolder = (VechileListHolder) viewHolder;
mHolder.renderDate(vechileList.get(pos));
}
#Override
public int getItemCount() {
if (vechileList != null)
return this.vechileList.size();
else
return 0;
}
public class VechileListHolder extends RecyclerView.ViewHolder implements
View.OnClickListener {
ArabicTextView vecName;
RelativeLayout img_layout;
ProgressBar progress;
ImageView imgView;
public VechileListHolder(View vi) {
super(vi);
vi.setOnClickListener(this);
img_layout = (RelativeLayout) vi.findViewById(R.id.img_layout);
vecName = (ArabicTextView) vi.findViewById(R.id.TVVecName);
progress = (ProgressBar) vi.findViewById(R.id.progress);
imgView = (ImageView) vi.findViewById(R.id.imgView);
}
public void renderDate(Vechiles item) {
imageLoaderHelper.loadImage(imgView, progress, item.getImg());
vecName.setText(item.getVecName());
}
#Override
public void onClick(View v) {
if (mItemClickListener != null)
mItemClickListener.onItemClickListener(getPosition(), v);
}
}
public void setOnItemClickListener(ItemClickListener itemClick) {
this.mItemClickListener = itemClick;
}
public ItemClickListener mItemClickListener;
public interface ItemClickListener {
public void onItemClickListener(int pos, View v);
}
public void updateList(ArrayList<Vechiles> vechileList) {
this.vechileList = vechileList;
notifyDataSetChanged();
}
public void removeItem(int pos){
this.vechileList.remove(pos);
notifyItemRemoved(pos);
}
}
and in Fragment or activity can
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
initListView();
}
private void initRecycleView(){
listView = (RecyclerView) v.findViewById(R.id.listView);
listView.getItemAnimator().setAddDuration(1000);
listView.getItemAnimator().setChangeDuration(1000);
listView.getItemAnimator().setMoveDuration(1000);
listView.getItemAnimator().setRemoveDuration(1000);
listView.setLayoutManager(new GridLayoutManager(getActivity(), 3));
listView.setAdapter(new TransportTypeAdapter(getActivity(), vecList));
}
then after data back from API can update adapter with new data by use method update
((VechileListHolder ) listView.getAdapter).updateList( vechileList);
in case went to remove any item by using Pos can do call method that in adapter removeItem(pos)
((VechileListHolder ) listView.getAdapter).removeItem(1);
hope this code help you