RecyclerView onCreateViewHolder method not calling - java

Below are my ShelflifeAdapter and HomeFragment classes:-
public class HomeFragment extends Fragment {
RecyclerView shelflifeRecyclerview;
ShelflifeAdapter shelflifeAdapter;
Product product;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_home, container, false);
shelflifeRecyclerview = rootView.findViewById(R.id.shelflifeRecyclerview);
shelflifeAdapter = new ShelflifeAdapter(getContext());
shelflifeRecyclerview.setAdapter(shelflifeAdapter);
shelflifeRecyclerview.setLayoutManager(new LinearLayoutManager(getContext()));
shelflifeRecyclerview.setHasFixedSize(true);
//fragment->fragment 데이터받기
Bundle bundle = getArguments(); //번들 받기
if(bundle != null){
product = new Product();
product = (Product) bundle.getSerializable("bundle");
shelflifeAdapter.addItem(product);
Log.d("TAG", shelflifeAdapter.getItemCount() +" 갯수");
}
return rootView;
}
}
public class ShelflifeAdapter extends RecyclerView.Adapter<ShelflifeAdapter.ViewHolder>{
ArrayList<Product> items = new ArrayList<Product>();
Context mContext;
ShelflifeAdapter(Context context){
mContext = context;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
Log.d("TAG","onCreateViewHolder 작동함");
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View itemView = inflater.inflate(R.layout.layout_shelflife,parent,false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder viewHolder, int position) {
Log.d("TAG","onBindViewHolder 작동함");
Product item = items.get(position);
viewHolder.setItem(item,mContext);
}
#Override
public int getItemCount() {
return items.size();
}
public void addItem(Product item){
if(item != null){
Log.d("TAG","addItem 작동함(item 추가) : " + item.toString());
items.add(item);
notifyDataSetChanged();
}else{
Log.d("TAG","addItem 작동함(item 못가져옴)");
}
}
public void setItems(ArrayList<Product> items){
this.items = items;
}
public Product getItem(int position){
return items.get(position);
}
static class ViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
TextView tv_shelflife;
LinearLayout itemContainer;
public ViewHolder(#NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.imageView);
tv_shelflife = itemView.findViewById(R.id.tv_shelflife);
itemContainer = itemView.findViewById(R.id.itemContainer);
}
public void setItem(Product item, Context context){
if(item != null){
Log.d("TAG","어댑터의 item : "+ item.toString());
if(item.getImage()==null){
Glide.with(itemView).load(R.drawable.no_image).override(48,48).into(imageView);
}else{
Glide.with(itemView).load(item.image).override(48,48).into(imageView);
}
tv_shelflife.setText(item.shelflifeDate);
}else{
Log.d("TAG","item이 null임" );
}
}
}
}
addItem(Product item) is working well
But onCreateViewHolder method is not working.
Any help is appreciated !!!

initialize recycler view first ,then set adapter for recycler view.
shelflifeAdapter = new ShelflifeAdapter(getContext());
shelflifeRecyclerview.setLayoutManager(new LinearLayoutManager(getContext()));
shelflifeRecyclerview.setHasFixedSize(true);
//Always set adapter after setLayoutManager, setHasFixedSize
shelflifeRecyclerview.setAdapter(shelflifeAdapter);
Bundle bundle = getArguments(); //번들 받기
if(bundle != null){
product = new Product();
product = (Product) bundle.getSerializable("bundle");
shelflifeAdapter.addItem(product);
Log.d("TAG", shelflifeAdapter.getItemCount() +" 갯수");
}
And make sure item is not null
Product item = items.get(position);
if(item!=null)
viewHolder.setItem(item,mContext);
pass context into glide
if(item.getImage()==null){
Glide.with(context).load(R.drawable.no_image).override(48,48).into(imageView);
}else{
Glide.with(context).load(item.image).override(48,48).into(imageView);
}
tv_shelflife.setText(item.shelflifeDate);

Related

Adapters in Java Android stuio

I'm trying to make and activity that uses fragment with viewpager2 and I'm having problem populating the grid view inside the viewpage2. and I'm having trouble using adapters. what are the steps I need to know to make this activity work?
this is my fragment class
public class item_frag extends Fragment{
Context context;
FragmentItemDisplayBinding binding;
String name, description, category, price, imageurl;
FirebaseStorage firebaseStorage;
FirebaseDatabase firebaseDatabase;
DatabaseReference databaseReference;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
firebaseDatabase = FirebaseDatabase.getInstance();
databaseReference = firebaseDatabase.getReference("inventory");
firebaseStorage = FirebaseStorage.getInstance();
name = databaseReference.getDatabase().getReference("inventory").toString();
description = databaseReference.getDatabase().getReference("inventory").toString();
category = databaseReference.getDatabase().getReference("inventory").toString();
price = databaseReference.getDatabase().getReference("inventory").toString();
imageurl = firebaseStorage.getReference("inventory").toString();
String[] itemname = {"hello"};
int[] itemimage = {R.drawable.unimas_logo};
View view = inflater.inflate(R.layout.fragment_item_display, container, false);
GridView gridView = (GridView) view.findViewById(R.id.grid_view);
item_frag_adapter itemFragAdapter = new item_frag_adapter(context, itemname, itemimage);
gridView.setAdapter(itemFragAdapter);
return inflater.inflate(R.layout.fragment_item_display, container, false);
}
}
this is my item fragment adapter class
public class item_frag_adapter extends BaseAdapter {
Context context;
String[] itemname;
int[] image;
LayoutInflater inflater;
public item_frag_adapter(Context context, String[] itemname, int[] image) {
this.context = context;
this.itemname = itemname;
this.image = image;
}
#Override
public int getCount() {
return itemname.length;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (inflater == null)
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null){
convertView = inflater.inflate(R.layout.item_card,null);
}
ImageView imageView = convertView.findViewById(R.id.idIVimage);
TextView textView = convertView.findViewById(R.id.idTVtext);
imageView.setImageResource(image[position]);
textView.setText(itemname[position]);
return convertView;
}
}

Clear bundler data

In my fragment I have an EditText which basically allows, when submitted, to query the values from Firebase Realtime Database and show them in a Recycler View.
Everything is fine when I search the first time but, when I search more than once, the previous results stay in the Recycler View.
I've tried to clear my lists but I got no success. I think I found the problem but I just can't solve it. I need to clear my bundle everytime I pass the retrieved values from the DB from one fragment to another. This is my fragment code (where I call the adaptor, not where I retrieve the DB values):
public class FilteredResultsFragment extends android.support.v4.app.Fragment {
ImageAdapter imageAdapter;
List<String> listOfImages = new ArrayList<>();
List<String> listOfNames = new ArrayList<>();
private RecyclerView recyclerView;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View viewFilteredResults = inflater.inflate(R.layout.fragment_filtered_results, container, false);
recyclerView = viewFilteredResults.findViewById(R.id.recyclerViewFiltered);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
imageAdapter = new ImageAdapter(listOfImages, listOfNames, getContext());
recyclerView.setAdapter(imageAdapter);
return viewFilteredResults;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (getArguments() != null) {
removeAll();
listOfImages.addAll(getArguments().getStringArrayList("listOfImages"));
listOfNames.addAll(getArguments().getStringArrayList("listOfNames"));
Log.d("IMAGENS", "img "+listOfImages);
Log.d("Nomes","nome "+listOfNames);
imageAdapter.notifyDataSetChanged();
}
}
public void removeAll(){
listOfImages.clear();
listOfNames.clear();
imageAdapter.notifyDataSetChanged();
}
}
As you can see, I've created a function that should allow me to clear the data... And this is my Adaptor:
public class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.ImageViewHolder> {
List<String> listaPaisesFiltrados;
List<String> listaNomesFiltrados;
android.content.Context context;
ImageAdapter(List<String> listaPaisesFiltrados, List<String> listaNomesFiltrados, android.content.Context c) {
this.listaPaisesFiltrados = listaPaisesFiltrados;
this.listaNomesFiltrados = listaNomesFiltrados;
this.context = c;
}
#NonNull
#Override
public ImageViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item_view, parent, false);
return new ImageViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull ImageViewHolder holder, int position) {
String imageUrl = listaPaisesFiltrados.get(holder.getAdapterPosition());
String nomePais = listaNomesFiltrados.get(holder.getAdapterPosition());
android.content.Context context1 = context.getApplicationContext();
Log.d("ADAPTER", "imageUrl : " + imageUrl + " position : " + holder.getAdapterPosition());
Typeface tpPaisNome = Typeface.createFromAsset(holder.itemView.getContext().getAssets(),"fonts/RobotoSlab-Bold.ttf"); // Define a Typeface
holder.textView.setTypeface(tpPaisNome);
holder.textView.setText(nomePais);
Glide.with(holder.imageView.getContext()).load(imageUrl).centerCrop().into(holder.imageView);
}
#Override
public int getItemCount() {
Log.d("ADAPTER", "SIZE : " + listaPaisesFiltrados.size());
return listaPaisesFiltrados.size();
}
public class ImageViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
TextView textView;
public ImageViewHolder(View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.imgPaisFiltrado);
textView = itemView.findViewById(R.id.txtNomePaisFiltrado);
}
}
}
EDIT
In my ExploreFragment (where I have the query and the EditText) I send two ArrayLists via Bundle to the fragment that opens the adaptor. I need to clear my Bundler but, when I use blunder.clear() than no value is passed to the other fragment and no image is displayed. This is my code
srcView.setOnEditorActionListener(new EditText.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
boolean handled = false;
if (actionId == EditorInfo.IME_ACTION_DONE) {
txtRecomendado.setVisibility(View.INVISIBLE);
scrollView.setVisibility(View.INVISIBLE);
final Bundle bundler = new Bundle();
bundler.clear();
FirebaseDatabase mDatabase = FirebaseDatabase.getInstance();
DatabaseReference paisNomeContinentes = mDatabase.getReference().child("paises");
Query queries = paisNomeContinentes.orderByChild("Nome").startAt(String.valueOf(srcView.getText())).endAt(String.valueOf(srcView.getText())+"\uf8ff");
Log.d("AQUIPUTO","teste "+String.valueOf(srcView.getText()));
queries.addListenerForSingleValueEvent(new com.google.firebase.database.ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
List<String> imagemPaisList = new ArrayList<>();
List<String> nomePaisList = new ArrayList<>();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
String imagemPais = ds.child("Imagem").getValue(String.class);
String nomePais = ds.child("Nome").getValue(String.class);
imagemPaisList.add(imagemPais);
nomePaisList.add(nomePais);
}
int urlCount = imagemPaisList.size();
// int randomImage = new Random().nextInt(urlCount);
for (int i = 0; i < nomePaisList.size(); i++) {
//Integer randomVariavel = new Random().nextInt(urlCount);
randomImagemPaisList.add(imagemPaisList.get(i));
randomNomePaisList.add(nomePaisList.get(i));
}
getFragmentManager().popBackStack();
FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
transaction.setCustomAnimations(R.anim.slide_up_info,R.anim.slide_down_info);
FilteredResultsFragment fragment = new FilteredResultsFragment();
bundler.putStringArrayList("listOfImages", (ArrayList<String>) randomImagemPaisList);
bundler.putStringArrayList("listOfNames", (ArrayList<String>) randomNomePaisList);
fragment.setArguments(bundler);
transaction.replace(R.id.fragContainerExploreFilteredResults, fragment);
transaction.addToBackStack(null);
transaction.commit();
}
How can I clear my bundle? I've tried to clear it after I use:
bundler.putStringArrayList("listOfImages", (ArrayList<String>) randomImagemPaisList);
bundler.putStringArrayList("listOfNames", (ArrayList<String>) randomNomePaisList);
fragment.setArguments(bundler);
And if I do this no value is passed from one fragment to another. I've tried to clear it when the fragment.trasaction is complete but I still get the same 'error'...
might be possible that updated data is not notify with recyclerview, you can create doRefresh method in adapter class and then update the list and notify it, please see the below code
Fragment Code
public class FilteredResultsFragment extends android.support.v4.app.Fragment {
ImageAdapter imageAdapter;
List<String> listOfImages = new ArrayList<>();
List<String> listOfNames = new ArrayList<>();
private RecyclerView recyclerView;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View viewFilteredResults = inflater.inflate(R.layout.fragment_filtered_results, container, false);
setAdapter();
return viewFilteredResults;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (getArguments() != null) {
listOfImages.clear();
listOfNames.clear();
listOfImages.addAll(getArguments().getStringArrayList("listOfImages"));
listOfNames.addAll(getArguments().getStringArrayList("listOfNames"));
Log.d("IMAGENS", "img "+listOfImages);
Log.d("Nomes","nome "+listOfNames);
setAdapter();
}
}
private void setAdapter() {
if (listOfImages != null && listOfNames != null) {
if (imageAdapter == null) {
imageAdapter = new ImageAdapter(getContext());
}
imageAdapter.doRefresh(listOfImages, listOfNames);
if (recyclerView.getAdapter() == null) {
recyclerView = viewFilteredResults.findViewById(R.id.recyclerViewFiltered);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(imageAdapter);
}
}
}
}
and Adapter class as below
public class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.ImageViewHolder> {
List<String> listaPaisesFiltrados;
List<String> listaNomesFiltrados;
android.content.Context context;
ImageAdapter(android.content.Context c) {
this.context = c;
}
public void doRefresh(List<String> listaPaisesFiltrados, List<String> listaNomesFiltrados) {
this.listaPaisesFiltrados = listaPaisesFiltrados;
this.listaNomesFiltrados = listaNomesFiltrados;
notifyDataSetChanged();
}
#NonNull
#Override
public ImageViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item_view, parent, false);
return new ImageViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull ImageViewHolder holder, int position) {
String imageUrl = listaPaisesFiltrados.get(holder.getAdapterPosition());
String nomePais = listaNomesFiltrados.get(holder.getAdapterPosition());
android.content.Context context1 = context.getApplicationContext();
Log.d("ADAPTER", "imageUrl : " + imageUrl + " position : " + holder.getAdapterPosition());
Typeface tpPaisNome = Typeface.createFromAsset(holder.itemView.getContext().getAssets(),"fonts/RobotoSlab-Bold.ttf"); // Define a Typeface
holder.textView.setTypeface(tpPaisNome);
holder.textView.setText(nomePais);
Glide.with(holder.imageView.getContext()).load(imageUrl).centerCrop().into(holder.imageView);
}
#Override
public int getItemCount() {
Log.d("ADAPTER", "SIZE : " + listaPaisesFiltrados.size());
return listaPaisesFiltrados.size();
}
public class ImageViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
TextView textView;
public ImageViewHolder(View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.imgPaisFiltrado);
textView = itemView.findViewById(R.id.txtNomePaisFiltrado);
}
}
}
you can try to create new adapter and set to your recycler.
listOfImages.clear();
listOfNames.clear();
/*
Adding your new searching data here
*/
recyclerView.setAdapter(new ImageAdapter(listOfImages, listOfNames, getContext());
recyclerView.invalidate();
When you try to clear by calling removeAll, you only clear the list objects from the Fragment class. What you need is to clear the list objects in your RecyclerView.Adapter class.
Try this:
Move your removeAll to your adapter. That way, you clear the list objects in that adapter.
In your Fragment, just call your removeAll from your Adapter.
Sample Code:
Fragment.java
//No more removeAll() here
public void callAdapterToRemove() {
imageAdapter.removeAll();
}
ImageAdapter.java
//Now it's here
public void removeAll() {
listaPaisesFiltrados.clear();
listaNomesFiltrados.clear();
notifyDataSetChanged();
}

Android Checkbox in Listview selecting automatically

in my android application I am displaying the contact list of phone in a list view and a check box in each row for selecting contacts. But when I am selecting a particular row about tenth row is also getting selected automatically. I am giving my code below, if any one knows please help..
public class ContactsAdapter extends BaseAdapter
{
private Context context;
private ArrayList<Contact> contacts;
public ContactsAdapter(Context context, ArrayList<Contact> contacts)
{
this.context = context;
this.contacts = contacts;
}
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridView;
final ViewHolder mHolder;
if (convertView == null)
{
// gridView = new View(context);
// get layout from mobile.xml
//gridView = inflater.inflate(R.layout.contact, null);
convertView = inflater.inflate(R.layout.contact, null);
mHolder = new ViewHolder();
mHolder.textName =(TextView) convertView.findViewById(R.id.name);
mHolder.textMobile =(TextView) convertView.findViewById(R.id.mobile);
mHolder.textSelector =(CheckBox) convertView.findViewById(R.id.selected);
convertView.setTag(mHolder);
));
}
else
{
mHolder = (ViewHolder) convertView.getTag();
mHolder.textSelector.setOnCheckedChangeListener(null);
}
mHolder.textMobile.setText(contacts.get(position).getMobile());
mHolder.textName.setText(contacts.get(position).getName());
mHolder.textSelector.setFocusable(false);
return convertView;
}
private class ViewHolder {
private TextView textMobile,textName;
private CheckBox textSelector;
}
#Override
public int getCount() {
return contacts.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
}
Well Thats because ViewHolder will recycle the Views everytime you Scroll
i suggest you to Use onCLick on ListItem instead checkbox
To overcome this Declare a SparseBooleanArray
SparseBooleanArray sba=new SparseBooleanArray();//this should be global
Then set the items checked state as soon as you render it
mHolder.textSelector =(CheckBox) convertView.findViewById(R.id.selected);
mHolder.textSelector.setChecked(sba.get(position));
Then write a onClickListener to you convertView and check it manually
convertView.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {
mHolder.textSelector.setChecked(isChecked);
sba.put(position,isChecked); //storing the state
}
}
);
**Well Now the sba has list items checked and you can use that for further Actions**
# Jocheved... edit your code like this...
public class ContactsAdapter extends BaseAdapter
{
private Context context;
private ArrayList<Contact> contacts;
SparseBooleanArray sba=new SparseBooleanArray();
public ContactsAdapter(Context context, ArrayList<Contact> contacts)
{
this.context = context;
this.contacts = contacts;
}
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final ViewHolder mHolder;
if (convertView == null)
{
convertView = inflater.inflate(R.layout.contact, null);
mHolder = new ViewHolder();
mHolder.textName =(TextView) convertView.findViewById(R.id.name);
mHolder.textMobile =(TextView) convertView.findViewById(R.id.mobile);
mHolder.textSelector =(CheckBox) convertView.findViewById(R.id.selected);
convertView.setTag(mHolder);
}
else
{
mHolder = (ViewHolder) convertView.getTag();
}
mHolder.textMobile.setText(contacts.get(position).getMobile());
mHolder.textName.setText(contacts.get(position).getName());
mHolder.textName.setSelected(true);
mHolder.textSelector.setChecked(sba.get(position));
mHolder.textSelector.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v) {
if(mHolder.textSelector.isChecked())
{
sba.put(position, true);
}
else
{
sba.put(position, false);
}
}
});
return convertView;
}
private class ViewHolder
{
private TextView textMobile,textName;
private CheckBox textSelector;
}
#Override
public int getCount() {
return contacts.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
}

Duplicate entries List View with Generic Adapter

I have a generic adapter to use with all kind of listView but I get duplicated items in a ListView. When I'm Scrolling back and down sometimes changes the item order. There is some threads about that but not with a generic adapter. I know Android reuse the Ui object but the view in getView is always null (said android Studio)
Here is my code about adapter :
Interface :
public interface Adaptable {
public View buildView(View v, LayoutInflater inflater, ViewGroup parent);
}
BaseView Class :
public abstract class BaseView<T,E> implements Adaptable{
private static final String TAG = "BaseView";
protected int layoutId;
protected T viewHolder;
protected E entity;
public BaseView(){
}
public BaseView(E entity, int layoutId){
this.entity = entity;
this.layoutId = layoutId;
}
protected void invokeView(View v){
try {
Field fs[] = viewHolder.getClass().getFields();
for (Field f : fs) {
InvokeView a = f.getAnnotation(InvokeView.class);
int id = a.viewId();
Log.d(TAG, "field name: " + f.getName());
Log.d(TAG, "view id: " + id);
Log.d(TAG, "class: " + f.getClass());
f.set(viewHolder, v.findViewById(id));
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
#SuppressWarnings("unchecked")
#Override
public View buildView(View v, LayoutInflater inflater, ViewGroup parent) {
// load the view
if (null == v) {
v = inflater.inflate(layoutId, parent, false);
// get the view
invokeView(v);
v.setTag(viewHolder);
} else {
viewHolder = (T) v.getTag();
}
// binding logic data to view
mappingData(viewHolder, entity, v.getContext());
return v;
}
protected abstract void mappingData(T viewHolder, E entity, Context mContext);
}
Custom adapter class :
public class CustomListAdapter extends BaseAdapter {
private LayoutInflater inflater;
private List<Adaptable> items;
#SuppressWarnings("unchecked")
public CustomListAdapter(List<?> items, Context c) {
this.items = (List<Adaptable>) items;
inflater = LayoutInflater.from(c);
}
#Override
public int getCount() {
return items.size();
}
#Override
public Object getItem(int position) {
return items.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
return items.get(position).buildView(convertView, inflater, parent); }
}
InvokeView Interface :
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.FIELD)
public #interface InvokeView {
int viewId();
}
Here how I set it in my activity :
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_home, container, false);
ListView listViewPlaces = (ListView) rootView.findViewById(R.id.listLocality);
List<PlacesView> lstPlaceView = new ArrayList<PlacesView>();
ArrayList<PlaceModel> listPlaces = getArguments().getParcelableArrayList("listPlaces");
for (int i = 0; i < listPlaces.size(); i++)
{
Log.d("id", listPlaces.get(i).getId());
PlacesView mv = new PlacesView(listPlaces.get(i), R.layout.list_row_places);
lstPlaceView.add(mv);
}
CustomListAdapter adapter = new CustomListAdapter(lstPlaceView, rootView.getContext());
listViewPlaces.setAdapter(adapter);
return rootView;
}
If anyone have an idea.
Thanks in advance for help.

Get parent layout from custom Adapter

Could anybody explain me, how to realize?
I have an activity with listview and footer with some elements(textview).
Listview built with custom adapter. Each listview item has few elements. And my question: how can i change textview in footer, from custom adapter, when i clicking on some listview's element?
Thx a lot!
/**** My adapter ****/
public class MyListAdapter extends ArrayAdapter<Product> implements UndoAdapter {
private final Context mContext;
private HashMap<Product, Integer> mIdMap = new HashMap<Product, Integer>();
ArrayList<Product> products = new ArrayList<Product>();
final int INVALID_ID = -1;
LayoutInflater lInflater;
String imagePath;
public MyListAdapter(Context context, int textViewResourceId, List<Product> prod) {
//super(context, textViewResourceId, prod);
super(prod);
lInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mContext = context;
for (int i = 0; i < prod.size(); i++) {
//add(prod.get(i));
mIdMap.put(prod.get(i),i);
}
}
#Override
public long getItemId(final int position) {
//return getItem(position).hashCode();
Product item = (Product) getItem(position);
return mIdMap.get(item);
}
#Override
public boolean hasStableIds() {
return true;
}
#Override
public View getView(final int position, View convertView, final ViewGroup parent) {
ViewHolder holder = null;;
Product p = getItem(position);
if (convertView == null) {
convertView = lInflater.inflate(R.layout.item, null);
//convertView.setBackgroundResource(R.drawable.rounded_corners);
int currentTheme = Utils.getCurrentTheme(convertView.getContext());
switch (currentTheme) {
case 0:
convertView.setBackgroundResource(R.drawable.rounded_corners);
break;
case 1:
convertView.setBackgroundResource(R.drawable.border);
break;
default:
convertView.setBackgroundResource(R.drawable.rounded_corners);
break;
}
holder = new ViewHolder();
holder.tvDescr = (TextView) convertView.findViewById(R.id.tvDescr);
holder.list_image = (ImageView) convertView.findViewById(R.id.list_image);
holder.products_amount = (TextView) convertView.findViewById(R.id.amountDigits);
holder.products_price = (TextView) convertView.findViewById(R.id.priceDigits);
holder.ivImage = (ImageView) convertView.findViewById(R.id.ivImage);
holder.unit = (TextView) convertView.findViewById(R.id.unit);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
if(p.getProductImageBitmap() != null && p.getProductImageBitmap() != "") {
Log.d("PATH -- ", p.getProductImageBitmap());
ImageLoader imageLoader = ImageLoader.getInstance();
DisplayImageOptions options = new DisplayImageOptions.Builder().cacheInMemory(true)
.resetViewBeforeLoading(true)
.showImageForEmptyUri(R.drawable.ic_launcher)
.showImageOnFail(R.drawable.ic_launcher)
/*.showImageOnLoading(R.id.progress_circular)*/
.build();
imageLoader.displayImage(p.getProductImageBitmap(), holder.list_image, options);
} else {
holder.list_image.setImageResource(R.drawable.ic_launcher);
}
holder.tvDescr.setText(p.getProductName());
holder.ivImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String deletedItem = getItem(position).getProductName();
MyListAdapter.this.remove(getItem(position));
if (MyListAdapter.this.getCount() > 0) {
Toast.makeText(mContext, deletedItem + " " + mContext.getString(R.string.deleted_item), Toast.LENGTH_SHORT).show();
MyListAdapter.this.notifyDataSetChanged();
} else {
Toast.makeText(mContext,mContext.getString(R.string.sklerolist_empty), Toast.LENGTH_SHORT).show();
}
}
});
//Функционал для большой картинки продукта
//открывается новое активити с большой картинкой
holder.list_image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
imagePath = getItem(position).getProductImageBitmap();
if(imagePath != null && imagePath != "") {
Pattern normalPrice = Pattern.compile("^file");
Matcher m2 = normalPrice.matcher(imagePath);
if (m2.find()) {
Intent myIntent = new Intent(view.getContext(), ViewImage.class).putExtra("imagePath", imagePath);
view.getContext().startActivity(myIntent);
}
}
}
});
holder.products_price.setText(fmt(p.getProductPrice()));
holder.products_amount.setText(fmt(p.getProductAmount()));
holder.unit.setText(p.getProductUnit());
return convertView;
}
public static String fmt(double d){
if(d == (long) d)
return String.format("%d",(long)d);
else
return String.format("%s",d);
}
static class ViewHolder {
ImageView list_image;
TextView tvDescr;
TextView products_amount;
TextView products_price;
TextView unit;
ImageView ivImage;
ProgressBar circleProgress;
}
#NonNull
#Override
public View getUndoView(final int position, final View convertView, #NonNull final ViewGroup parent) {
View view = convertView;
if (view == null) {
//view = LayoutInflater.from(mContext).inflate(R.layout.undo_row, parent, false);
view = lInflater.inflate(R.layout.undo_row, parent, false);
}
return view;
}
#NonNull
#Override
public View getUndoClickView(#NonNull final View view) {
return view.findViewById(R.id.undo_row_undobutton);
}
public View getHeaderView(final int position, final View convertView, final ViewGroup parent) {
TextView view = (TextView) convertView;
//View view = convertView;
if (view == null) {
//view = (TextView) LayoutInflater.from(mContext).inflate(R.layout.list_header, parent, false);
//view = lInflater.inflate(R.layout.list_header, parent, false);
}
//view.setText(mContext.getString(R.string.header, getHeaderId(position)));
return view;
}
public long getHeaderId(final int position) {
return position / 10;
}
}
Your ListView has a listener for the click events on list elements.
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
// Do something when a list item is clicked
}
But if you want to pas something else back from the adapter to the Activity or the Fragment that contains that ListView and Adapter, you should create a simple interface and set it as listener to your adapter. After that, set click events on your rows from within the adapter, and notify the Activity or Fragment using your own interface.
For example you have the interface defined like this
public interface OnItemClickedCustomAdapter {
public void onClick(ItemPosition position);
}
and in your Adapter class you will have a private member
private OnItemClickedCustomAdapter mListener;
and a method used to set the listener
public void setOnItemClickedCustomAdapter(OnItemClickedCustomAdapter listener){
this.mListener = listener;
}
From your Activity or Fragment where your ListView is defined, and your adapter is set, you will be able to call setOnItemClickedCustomAdapter with this as parameter, and there you go. Your activity will now listen for your events. To trigger an event, just call mListener.onClick() from your custom adapter. You can pass back data you need back to the Activity or Fragment, and from there you have access to your Header or Footer directly, and you can change the text on them.

Categories

Resources