Android. Java. RecyclerAdapter - java

I have two different card view in one layout. I need that The latest news is added to one card view, and the rest in another. For exapmle, on image
MyRecyclerAdapter code
public class MyRecyclerAdapter extends RecyclerView.Adapter<MyRecyclerAdapter.CustomViewHolder> {
private List<FeedItem> feedItemList;
private Context mContext;
public MyRecyclerAdapter(Context context, List<FeedItem> feedItemList) {
this.feedItemList = feedItemList;
this.mContext = context;
}
#Override
public CustomViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_row, null);
CustomViewHolder viewHolder = new CustomViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(CustomViewHolder customViewHolder, int i) {
FeedItem feedItem = feedItemList.get(i);
//Download image using picasso library
Picasso.with(mContext).load(feedItem.getThumbnail())
.error(R.drawable.placeholder)
.placeholder(R.drawable.placeholder)
.into(customViewHolder.imageView);
//Setting text view title
customViewHolder.textView.setText(Html.fromHtml(feedItem.getTitle()));
View.OnClickListener clickListener = new View.OnClickListener() {
#Override
public void onClick(View view) {
CustomViewHolder holder = (CustomViewHolder) view.getTag();
int position = holder.getPosition();
FeedItem feedItem = feedItemList.get(position);
Toast.makeText(mContext, feedItem.getTitle(), Toast.LENGTH_SHORT).show();
}
};
//Handle click event on both title and image click
customViewHolder.textView.setOnClickListener(clickListener);
customViewHolder.imageView.setOnClickListener(clickListener);
customViewHolder.textView.setTag(customViewHolder);
customViewHolder.imageView.setTag(customViewHolder);
}
#Override
public int getItemCount() {
return (null != feedItemList ? feedItemList.size() : 0);
}
public class CustomViewHolder extends RecyclerView.ViewHolder {
protected ImageView imageView;
protected TextView textView;
public CustomViewHolder(View view) {
super(view);
this.imageView = (ImageView) view.findViewById(R.id.thumbnail);
this.textView = (TextView) view.findViewById(R.id.title);
}
}
}

The approach I would use if I were in you, to accomplish what you posted in the picture is to override getItemViewType and have two different types of ViewHolder, once for the header, the one with the big image and the other adapter for the small rows. onBindViewHolder gets the type as parameter. In your case is int i.

I write a quickdemo like this:
private class MyCustomAdapter extends BaseAdapter {
private static final int TYPE_ITEM = 0;
private static final int TYPE_SEPARATOR = 1;
private static final int TYPE_MAX_COUNT = TYPE_SEPARATOR + 1;
private ArrayList mData = new ArrayList();
private LayoutInflater mInflater;
private TreeSet mSeparatorSet = new TreeSet();
public MyCustomAdapter() {
mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public void addItem(String item) {
mData.add(item);
notifyDataSetChanged();
}
public void addSeparator(String item) {
mData.add(item);
mSeparatorSet.add(mData.size() - 1);
notifyDataSetChanged();
}
#Override
public int getItemViewType(int position) {
return mSeparatorSet.contains(position) ? TYPE_SEPARATOR : TYPE_ITEM;
}
#Override
public int getViewTypeCount() {
return TYPE_MAX_COUNT;
}
#Override
public int getCount() {
return mData.size();
}
#Override
public Object getItem(int position) {
return mData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
int type = getItemViewType(position);
System.out.println("getView " + position + " " + convertView + "type " + type);
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
switch (type) {
case TYPE_ITEM:
convertView = mInflater.inflate(R.layout.item1, null);
holder.textView = (TextView) convertView.findViewById(R.id.text_view);
break;
case TYPE_SEPARATOR:
convertView = mInflater.inflate(R.layout.item2, null);
holder.textView = (TextView) convertView.findViewById(R.id.textSeparator);
break;
}
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.textView.setText(mData.get(position) + "");
return convertView;
}
}
public static class ViewHolder {
public TextView textView;
}
or if you want to use header and footer, create headerView layout:
View header = (View) getLayoutInflater().inflate(R.layout.headerView,null);
listView.addHeaderView(header);

Related

How can i modify getItemViewType() with adapter input as a string and cursor?

I have created a recycler view and want to put two lists in it.
The first list is just a string that gets changed into fonts, which I have implemented in the onBindView method.
The second list is the cursor which includes the favorite fonts of the users.
I followed this answer on SO but I don't have any idea how I'm going to modify the getItemViewType() method so that I can get to know which list type is currently calling for view.
My adapter code
here data is the class that contains the list of fonts
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final int VIEW_TYPE_TEXTVIEW = 0;
private final int VIEW_TYPE_ITEM_1 = 1;
private int total_no_of_row;
private Context context;
private String str;
private Cursor cursor;
private final LayoutInflater inflater;
public MyAdapter(Context context, int total_no_of_row, String str , Cursor cursor) {
this.context = context;
this.total_no_of_row = total_no_of_row;
this.str = str;
this.cursor = cursor;
inflater = LayoutInflater.from(context);
}
#Override
public int getItemViewType(int position) {
return super.getItemViewType(position);
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
if(viewType == VIEW_TYPE_TEXTVIEW) {
View view = inflater.inflate(R.layout.row_layout, parent, false);
return new Item1Holder(view);
}
else if (viewType == VIEW_TYPE_ITEM_1){
View view = inflater.inflate(R.layout.row_layout, parent, false);
return new Item2Holder(view);
}
return null;
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
if(holder instanceof Item1Holder){
data d = new data();
cursor.moveToPosition(position);
Log.d("this2",cursor.getInt(1)+"");
String temp = d.Convert(str, cursor.getInt(1));
((Item1Holder)holder).textView.setText(temp);
((Item1Holder)holder).rowNumber.setText("⚫");
((Item1Holder)holder).fav.setImageResource(R.drawable.ic_baseline_favorite_24);
}else if(holder instanceof Item2Holder){
data d = new data();
String temp = d.Convert(str, position);
((Item2Holder)holder).textView.setText(temp);
((Item2Holder)holder).rowNumber.setText((position + 1) + ".");
if (util.COPY) {
if (position == util.CURRENT_POSITION) {
((Item2Holder)holder).imageView.setBackgroundResource(R.drawable.background_when_row_clicked);
} else {
((Item2Holder)holder).imageView.setBackgroundResource(R.drawable.background_when_row_clicked_two);
}
}
}
}
#Override
public int getItemCount() {
return total_no_of_row + cursor.getCount();
}
class Item1Holder extends RecyclerView.ViewHolder {
TextView textView;
ImageView imageView , fav;
TextView rowNumber;
public Item1Holder(#NonNull View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.text_body);
imageView = itemView.findViewById(R.id.copy_png);
rowNumber = itemView.findViewById(R.id.row_number);
fav = itemView.findViewById(R.id.fav);
}
}
class Item2Holder extends RecyclerView.ViewHolder {
TextView textView;
ImageView imageView , fav;
TextView rowNumber;
public Item2Holder(#NonNull View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.text_body);
imageView = itemView.findViewById(R.id.copy_png);
rowNumber = itemView.findViewById(R.id.row_number);
fav = itemView.findViewById(R.id.fav);
}
}
}
in main activity
here temp is the string that users want to convert into the fonts
Cursor cursor = show();
myAdapter = new MyAdapter(this , 500 , temp , cursor);
recyclerView.setAdapter(myAdapter);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(linearLayoutManager);
I'm not a professional android developer I'm still learning the stuff. so sorry if my code is too bad to understand
You are passing null in the onCreateViewHolder() method, and not specified position in getItemViewType() method. All you have to do is, update your code. do not pass the null value in the onCreateViewHolder method. Below code, I've tried, and works perfectly. Happy coding...
private static final int CATEGORY = 1;
private static final int NAME = 2;
private Collection<CategorizedName> data;
#Override
public int getItemViewType(int position) {
if (items.get(position) instanceof Category) {
return CATEGORY;
} else if (items.get(position) instanceof Name) {
return NAME;
}
throw new RuntimeException('error');
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
RecyclerView.ViewHolder viewHolder;
LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext());
switch (viewType) {
case CATEGORY:
View categoryView = inflater.inflate(R.layout.viewholder_category, viewGroup,
false);
viewHolder = new CategoryViewHolder(categoryView);
break;
case NAME:
View nameView = inflater.inflate(R.layout.viewholder_name, viewGroup, false);
viewHolder = new NameViewHolder(nameView);
break;
}
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
switch (viewHolder.getItemViewType()) {
case USER:
CategoryViewHolder categoryViewHolder = (CategoryViewHolder) viewHolder;
bindCategoryViewHolder(categoryViewHolder, position);
break;
case IMAGE:
NameViewHolder nameViewHolder = (NameViewHolder) viewHolder;
bindNameViewHolder(nameViewHolder, position);
break;
}
}
Replace your getItemViewType() with this
#Override
public int getItemViewType(int position){
if(position < total_no_of_row){
return VIEW_TYPE_TEXTVIEW;
}
if(position - total_no_of_row < cursor.getCount()){
return VIEW_TYPE_ITEM_1;
}
return -1;
}
you can also refer to my answer this

show ads after every 3 item in recyclerview

I have implemented the code to show ads after every 3 item but first item it show after 4 items rest working good
Below is the code I have tried to achieve this.
I want to show ad after every 3 items.
I have taken two constant variable to manage
private class AdsAdapter extends RecyclerView.Adapter<AdsAdapter.Holder> {
List<Ads> list;
List<String> stringList;
private static final int AD_TYPE = 2;
private static final int CONTENT_TYPE = 1;
public AdsAdapter(List<Ads> list, List<String> stringList) {
this.list = list;
this.stringList = stringList;
}
#Override
public int getItemViewType(int position) {
if (position>1 && position % 4 == 0) {
return AD_TYPE;
}
return CONTENT_TYPE;
}
#NonNull
#Override
public Holder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
Log.e("TYPE", viewType + "");
View listItem;
Holder viewHolder = null;
switch (viewType) {
case AD_TYPE:
listItem =
layoutInflater.inflate(R.layout.list_item1, parent,
false);
viewHolder = new Holder(listItem);
break;
case CONTENT_TYPE:
listItem =
layoutInflater.inflate(R.layout.list_item, parent,
false);
viewHolder = new Holder(listItem);
break;
}
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull Holder holder, int
position) {
int viewType=getItemViewType(position);
switch (viewType)
{
case AD_TYPE:
holder.imageView.setVisibility(View.VISIBLE);
break;
case CONTENT_TYPE:
holder.textView.setVisibility(View.VISIBLE);
holder.textView.setText(stringList.get(position));
break;
}
}
#Override
public int getItemCount() {
return stringList.size();
}
public class Holder extends RecyclerView.ViewHolder {
TextView textView;
ImageView imageView;
public Holder(#NonNull View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.tv_string);
imageView = itemView.findViewById(R.id.iv);
}
}
}
In adapter position starts from 0 so you have to do position+1
#Override
public int getItemViewType(int position) {
if (position>1 && (position+1) % 4 == 0) {
return AD_TYPE;
}
return CONTENT_TYPE;
}

Recyclerview holder mixes on scroll

When scroll recyclerview some items mixes. After I add ads after every 15 items, holder get wrong data. Some items are vip items. I will change background color of these items. But when I scroll it dublicates mixes. How can I solve?
This is my adapter
private Context mCtx;
private List<Car> carList;
private RecyclerViewAnimator mAnimator;
private int AD_TYPE=1;
private int CONTENT_TYPE=2;
private int LIST_AD_DELTA=15;
public ProductAllCarAdapter(RecyclerView recyclerView,Context mCtx, List<Car> carList) {
this.mCtx = mCtx;
this.carList = carList;
mAnimator = new RecyclerViewAnimator(recyclerView);
}
#Override
public ProductAllCarAdapter.ProductViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType == AD_TYPE){
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.product_add_item, null);
ProductAllCarAdapter.ProductViewHolder vh = new ProductAllCarAdapter.ProductViewHolder(itemView);
mAnimator.onCreateViewHolder(itemView);
return vh;
} else {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.product_car_item, null);
ProductAllCarAdapter.ProductViewHolder vh = new ProductAllCarAdapter.ProductViewHolder(itemView);
mAnimator.onCreateViewHolder(itemView);
return vh;
}
}
#Override
public int getItemViewType(int position) {
if (position>0 && position % LIST_AD_DELTA == 0)
return AD_TYPE;
return CONTENT_TYPE;
}
#Override
public void onBindViewHolder(ProductAllCarAdapter.ProductViewHolder holder, int position) {
if (getItemViewType(position) == CONTENT_TYPE) {
final Car car = carList.get(holder.getAdapterPosition());
GlideApp.with(mCtx).load(car.getImg()).into(holder.imageView);
if (car.getVip() == 1) {
holder.relativeLayout.setBackgroundColor(ContextCompat.getColor(mCtx, R.color.colorVip));
holder.imageViewVIP.setVisibility(View.VISIBLE);
}
final String carid = String.valueOf(car.getCarid());
mAnimator.onBindViewHolder(holder.itemView, position);
} else {
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Context mcontext = view.getContext();
Bundle bundle = ActivityOptionsCompat.makeCustomAnimation(mcontext, android.R.anim.fade_in, android.R.anim.fade_out).toBundle();
Intent intent = new Intent(mcontext, AdsItem.class);
mcontext.startActivity(intent, bundle);
}
});
mAnimator.onBindViewHolder(holder.itemView, position);
}
}
private int getRealPosition(int position) {
if (LIST_AD_DELTA == 0) {
return position;
} else {
return position - position / LIST_AD_DELTA;
}
}
#Override
public long getItemId(int position) { return position; }
#Override
public int getItemCount() {
int additionalContent = 0;
if (carList.size() > 0 && carList.size() > LIST_AD_DELTA) {
additionalContent = ( carList.size() / LIST_AD_DELTA);
}
return carList.size() + additionalContent;
}
public static class ProductViewHolder extends RecyclerView.ViewHolder {
private View mView;
ImageView imageView, imageViewVIP;
RelativeLayout relativeLayout;
public ProductViewHolder(View itemView) {
super(itemView);
mView = itemView;
imageView = itemView.findViewById(R.id.imageView);
imageViewVIP = itemView.findViewById(R.id.imageViewVIP);
relativeLayout = itemView.findViewById(R.id.relativeLayoutpc);
}
public void setOnClickListener(View.OnClickListener listener) {
mView.setOnClickListener(listener);
}
}
I think problem onBindViewHolder function use wrong holder. ArrayList also return true value but on scroll it mixes.
You just have to add the corresponding else of the following if statement block.
if (car.getVip() == 1) {
holder.relativeLayout.setBackgroundColor(ContextCompat.getColor(mCtx, R.color.colorVip));
holder.imageViewVIP.setVisibility(View.VISIBLE);
} else {
holder.relativeLayout.setBackgroundColor(ContextCompat.getColor(mCtx, R.color.colorNormal));
holder.imageViewVIP.setVisibility(View.GONE);
}
This is inside your onBindViewHolder function where the view type is CONTENT_TYPE.
Hope that solves your problem.

Recycler View linear layout manager returning null

I have a recycler view which contains multiple items and each item in the recycler view contains a horizontal recycler view.The problem I am encountering is that the layout manager is null.
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setLayoutManager(android.support.v7.widget.RecyclerView$LayoutManager)' on a null object reference
This is my code so far.I have checked that the data I am receiving is intact.
RecipeAdapter ( The main adapter )
public class RecipeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private List<Object> items;
private final int RECIPE = 0, JOKE = 1;
public RecipeAdapter(Context context) {
this.context = context;
this.items = new ArrayList<>();
}
public void setItems(List<Object> items) {
this.items = items;
}
public void add(Object object) {
items.add(object);
notifyItemInserted(items.size());
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder viewHolder;
final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
switch (viewType) {
case RECIPE:
View recipe = inflater.inflate(R.layout.item_recipe, parent, false);
viewHolder = new ViewHolder_Recipe(recipe);
break;
case JOKE:
View joke = inflater.inflate(R.layout.item_joke, parent, false);
viewHolder = new ViewHolder_Joke(joke);
break;
default:
View recipe_default = inflater.inflate(R.layout.item_recipe, parent, false);
viewHolder = new ViewHolder_Recipe(recipe_default);
break;
}
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
switch (holder.getItemViewType()) {
case RECIPE:
ViewHolder_Recipe viewHolderRecipe = (ViewHolder_Recipe) holder;
configureRecipeHolder(viewHolderRecipe, position);
break;
case JOKE:
ViewHolder_Joke viewHolderJoke = (ViewHolder_Joke) holder;
configureJokeHolder(viewHolderJoke, position);
break;
default:
ViewHolder_Recipe viewHolder_recipe_default = (ViewHolder_Recipe) holder;
configureRecipeHolder(viewHolder_recipe_default, position);
break;
}
}
private void configureJokeHolder(ViewHolder_Joke viewHolderJoke, int position) {
}
private void configureRecipeHolder(ViewHolder_Recipe viewHolderRecipe, int position) {
RecipeDetailed recipe = (RecipeDetailed) items.get(position);
Glide.with(context)
.load(recipe.getImage())
.into(viewHolderRecipe.getRecipe_image());
viewHolderRecipe.getRecipe_name().setText(recipe.getTitle());
viewHolderRecipe.getRecipe_prep().setText(recipe.getReadyInMinutes());
viewHolderRecipe.getRecipe_serves().setText(recipe.getServings());
viewHolderRecipe.getIngredientAdapter().setIngredients(recipe.getExtendedIngredients());
}
#Override
public int getItemViewType(int position) {
if (items.get(position) instanceof RecipeDetailed) {
return RECIPE;
} else if (items.get(position) instanceof Joke) {
return JOKE;
}
return super.getItemViewType(position);
}
#Override
public int getItemCount() {
return items.size();
}
}
The ViewHolder for that Adapter -- ViewHolder_Recipe
public class ViewHolder_Recipe extends RecyclerView.ViewHolder {
private CircularImageView recipe_image;
private TextView recipe_name;
private TextView recipe_prep;
private TextView recipe_serves;
private RecyclerView recyclerView;
private RecipeIngredientAdapter ingredientAdapter;
public ViewHolder_Recipe(View itemView) {
super(itemView);
recipe_image = (CircularImageView) itemView.findViewById(R.id.recipe_image);
recipe_name = (TextView) itemView.findViewById(R.id.recipe_name);
recipe_prep = (TextView) itemView.findViewById(R.id.recipe_prep);
recipe_serves = (TextView) itemView.findViewById(R.id.recipe_serves);
recyclerView = (RecyclerView) itemView.findViewById(R.id.recyclerView);
ingredientAdapter = new RecipeIngredientAdapter(itemView.getContext());
recyclerView.setLayoutManager(new LinearLayoutManager(itemView.getContext()
, LinearLayoutManager.HORIZONTAL, false));
recyclerView.setAdapter(ingredientAdapter);
}
public RecipeIngredientAdapter getIngredientAdapter() {
return ingredientAdapter;
}
public CircularImageView getRecipe_image() {
return recipe_image;
}
public TextView getRecipe_name() {
return recipe_name;
}
public TextView getRecipe_prep() {
return recipe_prep;
}
public TextView getRecipe_serves() {
return recipe_serves;
}
public RecyclerView getRecyclerView() {
return recyclerView;
}
}
The child adapter -- RecipeIngredientAdapter
public class RecipeIngredientAdapter extends RecyclerView.Adapter<ViewHolderRecipeIngredient> {
private Context context;
private ArrayList<Ingredient> ingredients;
public RecipeIngredientAdapter(Context context) {
this.context = context;
}
public void setIngredients(ArrayList<Ingredient> ingredients) {
this.ingredients = ingredients;
}
#Override
public ViewHolderRecipeIngredient onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.item_recipe_ingredients, parent, false);
return new ViewHolderRecipeIngredient(view);
}
#Override
public void onBindViewHolder(ViewHolderRecipeIngredient holder, int position) {
final Ingredient ingredient = ingredients.get(position);
Glide.with(context)
.load(ingredient.getImage())
.into(holder.getIngredient_image());
}
#Override
public int getItemCount() {
return 0;
}
}
The viewholder for that is a simple viewholder which contains an image.
I have seen posts online which seem to do the exact same thing and get it working,what exactly am i missing here?
From the error, it sounds like the RecyclerView is null, not the LayoutManager. Make sure you are using the proper id from the layout. are you sure the proper layout id of the RecyclerView is R.id.recyclerView?

implement getFilter in customAdapter that extends BaseAdapter

premise: i'm newbie on Java and Android, and i've search a lot for this but i don't understand how implement getFilter in my code.
this is MainActivity (relevant code):
public void loadList() {
/* allProd and allSpec are ArrayList<String> */
String[] allProdString = allProd.toArray(new String[allProd.size()]);
String[] allSpecString = allSpec.toArray(new String[allSpec.size()]);
listViewAdapter = new ListViewAdapter(this, allProdString, allSpecString);
listView.setAdapter(listViewAdapter);
}
this is customAdapter:
public class ListViewAdapter extends BaseAdapter {
Activity context;
String title[];
String description[];
public ListViewAdapter(Activity context, String[] title, String[] description) {
super();
this.context = context;
this.title = title;
this.description = description;
}
public int getCount() {
return title.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
private class ViewHolder {
TextView txtViewTitle;
TextView txtViewDescription;
}
public View getView(int position, View convertView, ViewGroup parent) {
Typeface typeface = Typeface.createFromAsset(context.getAssets(), "font/Simple_Print.ttf");
ViewHolder holder;
LayoutInflater inflater = context.getLayoutInflater();
if (convertView == null) {
convertView = inflater.inflate(R.layout.tabella_prodotti, null);
holder = new ViewHolder();
holder.txtViewTitle = (TextView) convertView.findViewById(R.id.titoloProd);
holder.txtViewDescription = (TextView) convertView.findViewById(R.id.subtitoloProd);
holder.txtViewDescription.setTypeface(typeface);
holder.txtViewTitle.setTypeface(typeface);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
holder.txtViewTitle.setText(title [position]);
holder.txtViewDescription.setText(description [position]);
return convertView;
}
}
how can I implement this function to have the ability to search within an array, and show the filtered results in the listview?
if you need any other info just ask! thanks
I think that your adapter should look like this. Also I would not recommend to instantiate objects inside getView() i.e typeface object
public class ListViewAdapter extends BaseAdapter {
String title[];
String description[];
ArrayList<String> filteredTitleList;
ArrayList<String> filteredDescripionList;
Typeface typeface;
LayoutInflater inflater;
public ListViewAdapter(Activity context, String[] title, String[] description) {
super();
this.context = context;
this.title = title;
this.description = description;
typeface = Typeface.createFromAsset(context.getAssets(),"font/Simple_Print.ttf");
inflater = context.getLayoutInflater();
this.filteredTitleList = new ArrayList<String>();
this.filteredDescripionList = new ArrayList<String>();
applyFilter(null);
}
public void applyFilter(String filter){
filteredTitleList.clear();
filteredDescripionList.clear();
for(int i=0; i < this.title.length; i++){
String tempTitle = title[i];
String tempDesc = description[i];
if(filter == null || filter.equals("")){
this.filteredTitleList.add(tempTitle);
this.filteredDescripionList.add(tempDesc);
}
else if(tempTitle.toLowerCase().contains(filter.toLowerCase()) || tempDesc.toLowerCase().contains(filter.toLowerCase())){
this.filteredTitleList.add(tempTitle);
this.filteredDescripionList.add(tempDesc);
}
}
this.notifyDataSetChanged();
}
public int getCount() {
return filteredTitleList.size();
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return position;
}
private class ViewHolder {
TextView txtViewTitle;
TextView txtViewDescription;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.tabella_prodotti, null);
holder = new ViewHolder();
holder.txtViewTitle = (TextView) convertView.findViewById(R.id.titoloProd);
holder.txtViewDescription = (TextView) convertView.findViewById(R.id.subtitoloProd);
holder.txtViewDescription.setTypeface(typeface);
holder.txtViewTitle.setTypeface(typeface);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
holder.txtViewTitle.setText(this.filteredTitleList.get(position));
holder.txtViewDescription.setText(this.filteredDescriptionList.get(position));
return convertView;
}
}
I have found a solution and share with you, I added addTextChangedListener to inputSearch in MainActivity:
inputSearch.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
textLength = inputSearch.getText().length();
//allProd_sort and allSpec_sort are ArrayList for search
allProd_sort.clear();
allSpec_sort.clear();
String text = inputSearch.getText().toString();
//allProdString is the String get from ArrayList allProd
for (int y =0; y<allProdString.length; y++) {
//in my case the search works only if there are min 3 characters in search
if (textLength <= allProdString[y].length() && textLength >=3) {
if (Pattern.compile(Pattern.quote(text), Pattern.CASE_INSENSITIVE)
.matcher(allProdString[y]).find()) {
allProd_sort.add(allProdString[y]);
allSpec_sort.add(allSpecString[y]);
}
}
}
String[] allProdStringSort = allProd_sort.toArray(new String[allProd_sort.size()]);
String[] allSpecStringSort = allSpec_sort.toArray(new String[allSpec_sort.size()]);
listView.setAdapter(new ListViewAdapter(MainActivity.this, allProdStringSort, allSpecStringSort));
}
#Override
public void afterTextChanged(Editable editable) {
}
});

Categories