I have a listview with and adapter that changes the title (TextView) and an image (ImageView) of all single item. But I have a problem, I also have and inputsearch (edittext) with the function TextChangedListener to search any single item of the list view. But actualy this is mi code of the TextChangedListener:
/**
* Enabling Search Filter
* */
inputSearch.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// When user changed the Text
Alimentacion.this.adapter.getFilter().filter(cs);
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
@Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
}
});
This generales a null pointer in this line: Alimentacion.this.adapter.getFilter().filter(cs); I think that the null pointer is because when I'm going to search something I only want to search by the title but in the adapter I have the title and the image so tries to search the title and the image and returs the null pointer, I think. How can separate these thing to search only for the title? My full code: ** OncreateView of myfragment.xml** (the list view is in a fragment)
// List view
private ListView lv;
// Listview Adapter
ArrayAdapter<String> adapter;
ArrayAdapter<String> adapter2;
// Search EditText
EditText inputSearch;
// Set the Text to try this out
lv = (ListView)myInflatedView.findViewById(R.id.list_view);
inputSearch = (EditText) myInflatedView.findViewById(R.id.inputSearch);
// Listview Data
final String categorias[] = {"1. Huevos y Lacteos", "2. Carnes y Derivados", "3. Pescados y Mariscos", "4. Aceites y grasos", "5. Verduras y hortalizas",
"6. Frutas", "7. Bebidas",
"8. Comida Rapida", "9. Pasta y Cereales", "10. Bolleria y Snacks"};
Integer ImgCategorias[] = {R.drawable.cat1,R.drawable.cat2,R.drawable.cat3,R.drawable.cat4,R.drawable.cat5,R.drawable.cat6
,R.drawable.cat7,R.drawable.cat8,R.drawable.cat9,R.drawable.cat10};
// Pass results to ListViewAdapter Class
CustomList adapter = new
CustomList(this.getActivity(), categorias, ImgCategorias);
// Binds the Adapter to the ListView
lv.setAdapter(adapter);
// OLD ADAPTER (where only change the text, it works to the TextChangeListener)
/* adapter2 = new ArrayAdapter<String>(this.getActivity(), R.layout.adapter_categorias, R.id.TVTitulo, categorias);
lv.setAdapter(adapter2); */
/**
* Enabling Search Filter
* */
inputSearch.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// When user changed the Text (LINE OF THE NULLPOINTER)
Alimentacion.this.adapter.getFilter().filter(cs);
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
@Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
}
});
And the CustomList.java
public class CustomList extends ArrayAdapter<String>{
private final Activity context;
private final String[] categorias;
private final Integer[] ImgCategorias;
public CustomList(Activity context,
String[] categorias, Integer[] ImgCategorias) {
super(context, R.layout.adapter_categorias, categorias);
this.context = context;
this.categorias = categorias;
this.ImgCategorias = ImgCategorias;
}
@Override
public View getView(int position, View view, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View rowView= inflater.inflate(R.layout.adapter_categorias, null, true);
TextView txtTitle = (TextView) rowView.findViewById(R.id.TVTitulo);
ImageView imageView = (ImageView) rowView.findViewById(R.id.IVCategoria);
txtTitle.setText(categorias[position]);
imageView.setImageResource(ImgCategorias[position]);
return rowView;
}
}
In conclusion, I want if is posible have the images and the titles in diferents adapters and in the search function put only the adapter of the title. Or something that allows me search for the title with no error.. I have seen this question: android attaching multiple adapters to one adapter But I don't understand very well how to implement it to my app..
Thanks.
I have modified the code as below and it's working fine now. Please check and let me know:
public class Image {
String categorias;
Integer ImgCategorias;
public String getCategorias() {
return categorias;
}
public void setCategorias(String categorias) {
this.categorias = categorias;
}
public Integer getImgCategorias() {
return ImgCategorias;
}
public void setImgCategorias(Integer imgCategorias) {
ImgCategorias = imgCategorias;
}
}
Your Adapter class:
import java.util.ArrayList;
import java.util.Locale;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class CustomList extends BaseAdapter {
private Context context;
private ArrayList<Image> data;
private ArrayList<Image> listImage;
public CustomList(Context context, ArrayList<Image> listImage) {
this.context = context;
data = listImage;
this.listImage = new ArrayList<Image>();
this.listImage.addAll(listImage);
}
@Override
public View getView(int position, View view, ViewGroup parent) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
View rowView = inflater
.inflate(R.layout.adapter_categorias, null, true);
TextView txtTitle = (TextView) rowView.findViewById(R.id.TVTitulo);
ImageView imageView = (ImageView) rowView
.findViewById(R.id.IVCategoria);
txtTitle.setText(data.get(position).getCategorias());
imageView.setImageResource(data.get(position).getImgCategorias());
return rowView;
}
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int position) {
return data.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@SuppressLint("DefaultLocale")
public void filter(String charText) {
charText = charText.toLowerCase(Locale.getDefault());
data.clear();
if (charText.trim().length() == 0) {
data.addAll(listImage);
} else {
for (Image wp : listImage) {
if (wp.getCategorias().toLowerCase().contains(charText)) {
data.add(wp);
}
}
}
notifyDataSetChanged();
}
}
Activity Class:
import java.util.ArrayList;
import java.util.Locale;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
public class Alimentacion extends Activity {
Context context;
TextView txtTVtexto;
EditText txtInputSearch;
ListView list;
CustomList adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_alimentacion);
context = Alimentacion.this;
txtTVtexto = (TextView) findViewById(R.id.TVtexto);
txtInputSearch = (EditText) findViewById(R.id.inputSearch);
list = (ListView) findViewById(R.id.list_view);
ArrayList<Image> listImage = prepareImageList();
adapter = new CustomList(context, listImage);
list.setAdapter(adapter);
list.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int pos,
long id) {
Image image = (Image) list.getItemAtPosition(pos);
Toast.makeText(context, "Name: "+image.getCategorias(), Toast.LENGTH_LONG).show();
}
});
txtInputSearch.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
@Override
public void afterTextChanged(Editable arg0) {
String text = "";
try {
text = txtInputSearch.getText().toString().toLowerCase(Locale.getDefault());
} catch ( Exception e ) {
e.printStackTrace();
}
adapter.filter(text);
}
});
}
private ArrayList<Image> prepareImageList() {
ArrayList<Image> listImage = new ArrayList<Image>();
Image image = new Image();
image.setCategorias("1. Huevos y Lacteos");
image.setImgCategorias(R.drawable.ic_launcher);
listImage.add(image);
image = new Image();
image.setCategorias("2. Carnes y Derivados");
image.setImgCategorias(R.drawable.ic_launcher);
listImage.add(image);
image = new Image();
image.setCategorias("3. Pescados y Mariscos");
image.setImgCategorias(R.drawable.ic_launcher);
listImage.add(image);
image = new Image();
image.setCategorias("4. Aceites y grasos");
image.setImgCategorias(R.drawable.ic_stub);
listImage.add(image);
image = new Image();
image.setCategorias("5. Verduras y hortalizas");
image.setImgCategorias(R.drawable.share);
listImage.add(image);
image = new Image();
image.setCategorias("6. Frutas");
image.setImgCategorias(R.drawable.ic_launcher);
listImage.add(image);
image = new Image();
image.setCategorias("7. Bebidas");
image.setImgCategorias(R.drawable.ic_launcher);
listImage.add(image);
image = new Image();
image.setCategorias("8. Comida Rapida");
image.setImgCategorias(R.drawable.ic_launcher);
listImage.add(image);
image = new Image();
image.setCategorias("9. Pasta y Cereales");
image.setImgCategorias(R.drawable.ic_launcher);
listImage.add(image);
image = new Image();
image.setCategorias("10. Bolleria y Snacks");
image.setImgCategorias(R.drawable.ic_launcher);
listImage.add(image);
return listImage;
}
}
fragment_alimentacion.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="es.bawi.testdeporte.Alimentacion" >
<!-- TODO: Update blank fragment layout -->
<TextView
android:id="@+id/TVtexto"
android:layout_width="fill_parent"
android:layout_height="30dp"
android:gravity="center_horizontal|center_vertical"
android:text="Blank Fragment" />
<!-- Editext for Search -->
<EditText
android:id="@+id/inputSearch"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/TVtexto"
android:hint="Productos"
android:inputType="textVisiblePassword" />
<!-- List View -->
<ListView
android:id="@+id/list_view"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/inputSearch" />
</RelativeLayout>
adapter_categorias.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/LinearLayout1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@android:color/holo_blue_light"
android:paddingBottom="2dp" >
<RelativeLayout
android:layout_width="fill_parent"
android:background="@android:color/holo_green_light"
android:layout_height="70dp">
<ImageView
android:id="@+id/IVCategoria"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerVertical="true"
android:src="@drawable/ic_launcher"
android:focusable="false" />
<TextView
android:id="@+id/TVTitulo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_centerVertical="true"
android:layout_toRightOf="@id/IVCategoria"
android:text="Categoria"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/TVCalorias"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="@+id/TVTitulo"
android:paddingTop="0dp"
android:text="Nº Productos"
android:textAppearance="?android:attr/textAppearanceSmall" />
</RelativeLayout>
</LinearLayout>