I have a listview with a custom adapter, and Im trying to use SearchView with a CustomFilter. But the search is not "fully" working.
When I search for something that is on the viewable area of the listview, it is able to search, and all nonviewable area is not being included in the search.
Here is a video on whats going on:
https://youtu.be/2Z9FZMlNmGw
main
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_board_game_list, container, false);
this.listView = (ListView) view.findViewById(R.id.listView);
DatabaseAccess databaseAccess = DatabaseAccess.getInstance(this.getContext());
databaseAccess.open();
List<String> boardgamesNames = databaseAccess.getNames();
List<String> urls = databaseAccess.getUrls();
adapter = new bgAdapter(getContext(), R.layout.row_layout);
adapterOriginal = new bgAdapter(getContext(), R.layout.row_layout);
databaseAccess.close();
listView.setAdapter(adapter);
int i = 0;
for(String name: boardgamesNames) {
boardgameListRow data = new boardgameListRow(urls.get(i), boardgamesNames.get(i));
i++;
adapter.add(data);
adapterOriginal.add(data);
}
listView.setDivider(null);
listView.setDividerHeight(0);
searchView = (SearchView)view.findViewById(R.id.searchId);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
if (newText.length() > 0) {
adapter.getFilter().filter(newText);
}
return false;
}
});
searchView.setOnCloseListener(new SearchView.OnCloseListener() {
#Override
public boolean onClose() {
BoardGameListFragment fragment= new BoardGameListFragment();
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container,fragment);
fragmentTransaction.commit();
//adapter = adapterOriginal;
return true;
}
});
// Inflate the layout for this fragment
return view;
}
}
Here is the Adapter:
https://github.com/Shank09/AndroidTemp/blob/master/bgAdapter.java
I think you need to call notifyDataSetChanged() in onQueryTextChange
I fixed it, I was using the wrong variable in bgAdapter. Please remove this question if possible.
public class Listbyoperator extends Activity {
ListView lstdetail;
Activity act;
EditText search;
ArrayList<DetailModel> detail=new ArrayList<DetailModel>();
DetailaAdapter dadapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_listbyoperator);
act=this;
lstdetail=(ListView) findViewById(R.id.Listbyoperator_detaillist);
search=(EditText) findViewById(R.id.editsearch);
search.setPadding(10, 0, 0, 0);
search.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
String text = search.getText().toString().toLowerCase(Locale.getDefault());
dadapter.filter(text);
}
#Override
public void beforeTextChanged(CharSequence arg0, int arg1,
int arg2, int arg3) {
// TODO Auto-generated method stub
}
#Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
});
DetailModel d=new DetailModel("1","HARDIP","saahi");
detail.add(d);
DetailModel d1=new DetailModel("2","jalpa","sadfsadf");
detail.add(d1);
dadapter=new DetailaAdapter(act, detail);
lstdetail.setAdapter(dadapter);
dadapter.notifyDataSetChanged();
lstdetail.setEnabled(true);
}
}
/*Detail Model*/
public class DetailModel
{
public String d_id,d_name,d_decription;
public String getD_id() {
return d_id;
}
public void setD_id(String d_id) {
this.d_id = d_id;
}
public String getD_name() {
return d_name;
}
public void setD_name(String d_name) {
this.d_name = d_name;
}
public String getD_decription() {
return d_decription;
}
public void setD_decription(String d_decription) {
this.d_decription = d_decription;
}
public DetailModel(String s1,String s2,String s3)
{
this.d_id=s1;
this.d_name=s2;
this.d_decription=s3;
}
}
/*detail adapter */
public class DetailaAdapter extends BaseAdapter{
Context mContext;
private List<DetailModel> data=null;
private ArrayList<DetailModel> arraylist;
private static LayoutInflater inflater=null;
private static String String=null,valid;
public boolean flag=true;
public DetailaAdapter(Context context,List<DetailModel> data)
{
mContext = context;
this.data = data;
inflater = LayoutInflater.from(mContext);
this.arraylist = new ArrayList<DetailModel>();
this.arraylist.addAll(data);
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return data.size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return data.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View vi=convertView;
if(convertView==null)
inflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
vi = inflater.inflate(R.layout.list_detail, null);
final TextView t1,t2,t3,t4,t5;
t1=(TextView)vi.findViewById(R.id.list_detail_text1);
t2=(TextView)vi.findViewById(R.id.list_detail_textview2);
t3=(TextView)vi.findViewById(R.id.list_detail_text2);
DetailModel da =new DetailModel(String, String,String);
da=data.get(position);
final String a1,a2,a3;
a1=da.d_id;
a2=da.d_name;
a3=da.d_decription;
t2.setText(a3);//description
t3.setText(a2);//name
return vi;
}
public void filter(String charText)
{
charText = charText.toLowerCase(Locale.getDefault());
data.clear();
if (charText.length() == 0) {
data.addAll(arraylist);
}
else
{
for (DetailModel wp : arraylist)
{
if (wp.getD_decription().toLowerCase(Locale.getDefault()).contains(charText) || wp.getD_name().toLowerCase(Locale.getDefault()).contains(charText))
{
data.add(wp);
}
}
}
notifyDataSetChanged();
}
}
Related
I have one listview and adapter ImageButton for delete data, but I don't know how to delete data by setOnClick. I need to click ImageButton and delete data. I have data type room not null.
public class OrgManageRoom extends AppCompatActivity {
private ListView listView;
private ArrayAdapter<String> arrayAdapter;
private ArrayList<String> list_of_rooms = new ArrayList<>();
ArrayList<HashMap<String, String>> MyArrList;
public ArrayList<String> arr;
public ArrayAdapter adapter;
private DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference().getRoot();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_org_manage_room);
// listView = (ListView)findViewById(R.id.listView);
// listView.setAdapter(new ImageAdapter(this));
// arrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,list_of_rooms);
// listView.setAdapter(arrayAdapter);
createAdapter();
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent i = new Intent(OrgManageRoom.this,OrgAddUser.class);
startActivity(i);
}
});
}
private void createAdapter() {
listView = (ListView)findViewById(R.id.listView);
listView.setAdapter(new ImageAdapter(this));
mDatabase = FirebaseDatabase.getInstance().getReference().child("AllRoom");
mDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Set<String> set = new HashSet<String>();
Iterator i = dataSnapshot.getChildren().iterator();
while (i.hasNext()){
set.add(((DataSnapshot)i.next()).getKey());
}
list_of_rooms.clear();
list_of_rooms.addAll(set);
// arrayAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
public class ImageAdapter extends BaseAdapter {
private Context context;
public ImageAdapter(Context c) {
// TODO Auto-generated method stub
context = c;
}
public int getCount() {
// TODO Auto-generated method stub
return list_of_rooms.size();
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.deleteroom, null);
}
// ColImgID
TextView txtPosition = (TextView) convertView.findViewById(R.id.ColImgDesc);
txtPosition.setPadding(10, 0, 0, 0);
txtPosition.setText(list_of_rooms.get(position));
ImageButton cmdShared = (ImageButton) convertView.findViewById(R.id.imgCmdShared);
cmdShared.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Toast.makeText(OrgManageRoom.this, "test" + list_of_rooms.get(position), Toast.LENGTH_LONG).show();
}
});
return convertView;
}
}
}
Sorry, I edit all code and I make project chat firebase and show listview listroom for add user and delete user and manageroom. It deletes room edit nameroom. Same I need to click imagebutton for delete listroom.
hello to every one i have a custom list view with a search and animation all works cool but in search i have a little problem . I would like to, for example, I search for a word in a sentence.
But the way I used to enter the letters i have to put them in sequence.
here is my code:
public class MainActivity extends Activity {
ListView list;
ListViewAdapter adapter;
EditText editsearch;
String[] country;
Typeface tf;
ArrayList<WorldPopulation> arraylist = new ArrayList<WorldPopulation>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listview_main);
editsearch = (EditText) findViewById(R.id.search);
list = (ListView) findViewById(R.id.listview);
tf = Typeface.createFromAsset(getAssets(), "fonts/BKOODB.TTF");
country = new String[54];
for (int x = 1; x < 54 + 1; x = x + 1) {
String this_subject = "mo_" + String.valueOf(x);
int resID = getResources().getIdentifier(this_subject, "string", getPackageName());
country[x - 1] = getResources().getString(resID);
}
for (int i = 0; i < 54; i++) {
WorldPopulation wp = new WorldPopulation(country[i]);
// Binds all strings into an array
arraylist.add(wp);
}
adapter = new ListViewAdapter(this, arraylist);
list.setAdapter(adapter);
editsearch.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
String text = editsearch.getText().toString().toLowerCase(Locale.getDefault());
adapter.filter(text);
}
#Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
#Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
});
list.setOnScrollListener(new OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
hideKeyboard();
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
});
new CountDownTimer(500, 500) {
#Override
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
hideKeyboard();
}
}.start();
}
public class WorldPopulation {
private String country;
public WorldPopulation(String country) {
this.country = country;
}
public String getCountry() {
return this.country;
}
}
public class ListViewAdapter extends BaseAdapter {
// Declare Variables
Context mContext;
LayoutInflater inflater;
private List<WorldPopulation> worldpopulationlist = null;
private ArrayList<WorldPopulation> arraylist;
Animation animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.slide_in_right);
public ListViewAdapter(Context context, List<WorldPopulation> worldpopulationlist) {
mContext = context;
this.worldpopulationlist = worldpopulationlist;
inflater = LayoutInflater.from(mContext);
this.arraylist = new ArrayList<WorldPopulation>();
this.arraylist.addAll(worldpopulationlist);
}
public class ViewHolder {
TextView country;
}
#Override
public int getCount() {
return worldpopulationlist.size();
}
#Override
public WorldPopulation getItem(int position) {
return worldpopulationlist.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(final int position, View view, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View row;
row = inflater.inflate(R.layout.listview_item, parent, false);
TextView textview = (TextView) row.findViewById(R.id.country);
ImageView im = (ImageView) row.findViewById(R.id.imageitem);
im.setImageResource(R.drawable.hair);
textview.setText(worldpopulationlist.get(position).getCountry());
textview.setTypeface(tf);
Animation animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.slide_in_right);
row.startAnimation(animation);
row.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// *********************************************************
// in here it does not send right number to secend activity*
// *********************************************************
int orgPos = 0;
if (country.length != worldpopulationlist.size()) {
notifyDataSetChanged();
// The list on which we clicked is sorted!
String clickedText = worldpopulationlist.get(position).toString();
int i1 = 0;
boolean found = false;
while (i1 < country.length && found == false) {
if (clickedText == country[i1]) {
orgPos = i1;
found = true;
} else {
i1++;
}
}
Intent i2 = new Intent(mContext, SingleItemView.class);
String Subject_number = String.valueOf(orgPos + 1);
i2.putExtra("subject_number", Subject_number);
startActivity(i2);
} else {
Intent i = new Intent(mContext, SingleItemView.class);
String Subject_number = String.valueOf(position + 1);
i.putExtra("subject_number", Subject_number);
startActivity(i);
}
}
});
return row;
}
// Filter Class
public void filter(String charText) {
charText = charText.toLowerCase(Locale.getDefault());
worldpopulationlist.clear();
if (charText.length() == 0) {
worldpopulationlist.addAll(arraylist);
} else {
for (final WorldPopulation wp : arraylist) {
if (wp.getCountry().toLowerCase(Locale.getDefault()).contains(charText)) {
worldpopulationlist.add(wp);
}
}
}
notifyDataSetChanged();
}
}
private void hideKeyboard() {
View view = this.getCurrentFocus();
if (view != null) {
InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
}
try doing it in afterTextChanged Method because this allows you to enter all the text. and follow this link
public void afterTextChanged(Editable s) {
}
Try with custom adapter.
this will help you.Link
public class EpisodeScreen extends Activity implements OnClickListener,OnItemClickListener,IServerResponse {
private String image;
private String episodediscription;
private String video;
private ListView episodelist=null;
private ArrayList<Object> _EpisodeList=new ArrayList<Object>();
private EpisodeAdapter mAdapter=null;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.episode_list);
episodelist=(ListView)findViewById(R.id.listview1);
episodelist.setOnItemClickListener(this);
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.play:
Log.i("click","sucess");
break;
default:
break;
}
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
getEpisode();
}
public void getEpisode() {
if (NetworkAvailablity.checkNetworkStatus(EpisodeScreen.this)) {
ArrayList<NameValuePair> requestParaList = new ArrayList<NameValuePair>();
requestParaList.add(new BasicNameValuePair("issue_id","1"));
WebServiceCommunicator.getInstance().registerForServerResponse(
(IServerResponse) EpisodeScreen.this);
WebServiceCommunicator.getInstance().callGetAppWebService(
Constant.showDialog, this, WebServiceConstants.getMethodUrl(WebServiceConstants.METHOD_NAME_GET_EPISODE_DETAILS),
EpisodeScreen.this, Constant.PID_EPISODE, false,
requestParaList);
} else {
Constant.showAlertDialog(Constant.errorTitle,
Constant.MSG_CHECK_INTERNET_SETTING,
EpisodeScreen.this, false);
}
}
#Override
public void serverResponse(String response, int processid) {
// TODO Auto-generated method stub
Message msg = new Message();
msg.obj = response;
msg.arg1 = processid;
_handler.sendMessage(msg);
}
private Handler _handler = new Handler() {
public void handleMessage(Message msg) {
String respons=msg.obj.toString();
switch (msg.arg1) {
case Constant.PID_EPISODE:
if(respons!=null ){
try{
JSONObject jsonObj=new JSONObject(respons);
JSONArray jArray=jsonObj.optJSONArray("Episode Detail");
if(jArray!=null){
for(int i =0;i<jArray.length();i++){
JSONObject jsonObject=jArray.getJSONObject(i);
episodebean bean=new episodebean();
bean.setEpisode_image(jsonObject.getString("Episode-image"));
bean.setEpisode_discription(jsonObject.getString("Episode-description"));
bean.setEpisode_video(jsonObject.getString("Episode-video"));
_EpisodeList.add(bean);
}
mAdapter=new EpisodeAdapter(EpisodeScreen.this, _EpisodeList);
episodelist.setAdapter(mAdapter);
/**/
/*if(_EpisodeList.size()!=0){
mAdapter=new EpisodeAdapter(EpisodeScreen.this, _EpisodeList);
episodelist.setAdapter(mAdapter);
}*/
}
}
catch (JSONException e) {
}
}
break;
default:
break;
}
}
};
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "ok........", Toast.LENGTH_LONG).show();
}
}
here is adapter
public class EpisodeAdapter extends BaseAdapter {
private LayoutInflater _mInflater = null;
private ArrayList<Object> _EpisodeList=null;
private Context ctx = null;
private UserImageLoaderWithCache imageLoader=null;
public EpisodeAdapter(Context context,
ArrayList<Object> _episodeList) {
// TODO Auto-generated constructor stub
this.ctx = context;
this._EpisodeList = _episodeList;
imageLoader=new UserImageLoaderWithCache(context);
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return _EpisodeList.size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return _EpisodeList.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
static class ViewHolder {
public TextView txtViewTitle;
public ImageView pic;
public TextView tvurl;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
LayoutInflater linf = (LayoutInflater) ctx
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = linf.inflate(R.layout.episode_screen, null);
// view.imgViewFlag.setScaleType(ImageView.ScaleType.CENTER_CROP);
holder.txtViewTitle = (TextView) convertView.findViewById(R.id.tv_episode);
holder.tvurl=(TextView)convertView.findViewById(R.id.tv_url);
holder.pic = (ImageView) convertView.findViewById(R.id.iv_episode);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final episodebean bean=(episodebean)_EpisodeList.get(position);
holder.txtViewTitle.setText(bean.getEpisode_discription());
holder.tvurl.setText(bean.getEpisode_video());
imageLoader.display(bean.getEpisode_image(), holder.pic, R.drawable.ic_launcher);
return convertView;
}}
I am using ListView in which I have to show data, which is coming from server. My ListView is not showing anything while response is coming (although it is showing in logcat) What do I do? Please help.
Thank you.
try to change some code on your adapter at method: getItemId
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
let us know if this work.
It may be help u..replace your handler
private Handler _handler = new Handler() {
public void handleMessage(Message msg) {
switch (id) {
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
I have a listview that has a custom adapter, and I was trying to make it searchable using an Action Item. When I click the search icon in the action bar, the edit text comes up, but when I enter text and click "done" on the keyboard, nothing happens.
Here is the main class:
public class ItemId extends SherlockListActivity {
EditText editsearch;
ArrayAdapter<String> adapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Context ctx = getApplication();
Resources res = ctx.getResources();
String[] options = res.getStringArray(R.array.item_ids);
String[] ids = res.getStringArray(R.array.item_names);
TypedArray icons = res.obtainTypedArray(R.array.item_images);
adapter = new ItemIDAdapter(ctx, R.layout.idslistitem, ids, options, icons);
setListAdapter(adapter );
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Get the options menu view from menu.xml in menu folder
getSupportMenuInflater().inflate(R.menu.items_menu, menu);
// Locate the EditText in menu.xml
editsearch = (EditText) menu.findItem(R.id.menu_search).getActionView();
// Capture Text in EditText
editsearch.addTextChangedListener(textWatcher);
// Show the search menu item in menu.xml
MenuItem menuSearch = menu.findItem(R.id.menu_search);
menuSearch.setOnActionExpandListener(new OnActionExpandListener() {
// Menu Action Collapse
#Override
public boolean onMenuItemActionCollapse(MenuItem item) {
// Empty EditText to remove text filtering
editsearch.setText("");
editsearch.clearFocus();
return true;
}
// Menu Action Expand
#Override
public boolean onMenuItemActionExpand(MenuItem item) {
// Focus on EditText
editsearch.requestFocus();
// Force the keyboard to show on EditText focus
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
return true;
}
});
// Show the settings menu item in menu.xml
MenuItem menuSettings = menu.findItem(R.id.home);
// Capture menu item clicks
menuSettings.setOnMenuItemClickListener(new OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
Intent intent2 = new Intent(ItemId.this, Home.class);
startActivity(intent2);
return true;
}
});
return true;
}
// EditText TextWatcher
private TextWatcher textWatcher = new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
String text = editsearch.getText().toString()
.toLowerCase(Locale.getDefault());
adapter.getFilter().filter(text);
};
#Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
#Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
};
}
And here is the Adapter class:
public class ItemIDAdapter extends ArrayAdapter<String> implements Filterable {
public LayoutInflater mInflater;
public String[] mStrings;
public String[] mIds;
public TypedArray mIcons;
public int mViewResourceId;
public ItemIDAdapter(Context ctx, int viewResourceId,
String[] strings, String[] ids, TypedArray icons) {
super(ctx, viewResourceId, strings);
mInflater = (LayoutInflater)ctx.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
mStrings = strings;
mIds = ids;
mIcons = icons;
mViewResourceId = viewResourceId;
}
#Override
public int getCount() {
return mStrings.length;
}
#Override
public String getItem(int position) {
return mStrings[position];
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = mInflater.inflate(mViewResourceId, null);
ImageView iv = (ImageView)convertView.findViewById(R.id.option_icon);
iv.setImageDrawable(mIcons.getDrawable(position));
TextView tv = (TextView)convertView.findViewById(R.id.option_text);
tv.setText(mStrings[position]);
TextView tv1 = (TextView)convertView.findViewById(R.id.itemids);
tv1.setText(mIds[position]);
return convertView;
}
}
If anyone has any idea as to why nothing happens when I search, or knows how to fix it, it'd be greatly appreciated. Thanks!!
You need to implement a custom filter. Have a look at this post here someone else has had a similar problem which he solved: https://stackoverflow.com/a/8258457/2045570
Below is mine code, which is working perfectly:-
public class ExpenditureAdapter extends ArrayAdapter<Expenditure> implements Filterable {
ArrayList<Expenditure> listArray;
ArrayList<Expenditure> filteredlistArray;
private Filter mFilter;
public ExpenditureAdapter(#NonNull Context context, ArrayList<Expenditure> list) {
super(context,0, list);
listArray=list;
filteredlistArray=list;
}
#Override
public int getCount() {
return filteredlistArray.size(); // total number of elements in the list
}
public void add(Expenditure object) {
listArray.add(object);
this.notifyDataSetChanged();
}
public Filter getFilter() {
if (mFilter == null) {
mFilter = new CustomFilter();
}
return mFilter;
}
#Override
public Expenditure getItem(int i) {
return filteredlistArray.get(i); // single item in the list
}
#Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
}
#Override
public long getItemId(int i) {
return i; // index number
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
Expenditure expenditure = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.listexpenditure, parent, false);
}
// Lookup view for data population
TextView ExpId = (TextView) convertView.findViewById(R.id.ExpId);
TextView ExDate = (TextView) convertView.findViewById(R.id.ExDate);
TextView ExpAmt = (TextView) convertView.findViewById(R.id.ExpAmt);
TextView ExpDetail = (TextView) convertView.findViewById(R.id.ExpDetail);
// Populate the data into the template view using the data object
ExpId.setText(expenditure.ExpId);
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
String dateTime = dateFormat.format(expenditure.ExpDate);
ExDate.setText(dateTime);
ExpAmt.setText(String.valueOf(expenditure.ExpAmt));
ExpDetail.setText(expenditure.ExpDetail);
return convertView;
}
private class CustomFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if(constraint == null || constraint.length() == 0) {
ArrayList<Expenditure> list = new ArrayList<Expenditure>(listArray);
results.values = list;
results.count = list.size();
} else {
ArrayList<Expenditure> newValues = new ArrayList<Expenditure>();
for(int i = 0; i < listArray.size(); i++) {
Expenditure e_item = listArray.get(i);
if(e_item.ExpDetail.contains(constraint)) {
newValues.add(e_item);
}
}
results.values = newValues;
results.count = newValues.size();
}
return results;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
filteredlistArray = (ArrayList<Expenditure>) results.values;
notifyDataSetChanged();
}
}
and use it in your code as below:-
private TextWatcher textWatcher = new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
String text = txtSearch.getText().toString()
.toLowerCase(Locale.getDefault());
adapter.getFilter().filter(text);
};
#Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
#Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
};
ive implented a searchbar into my ListView and so far it works correctly except
that the adapter is acting weird. Everytime i call its clear function my listview still shows the "old" content.
public abstract class MYLISTITEM extends BaseAdapter {
private Context activity;
private List<String> data;
private static LayoutInflater inflater=null;
private int ItemIcon;
private boolean moreVis;
public MYISTITEM(Context a, int IconID,boolean vis) {
activity = a;
data = new ArrayList<String>();
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ItemIcon = IconID;
moreVis = vis;
}
public void add(String object)
{
data.add(object);
notifyDataSetChanged();
}
public void replace(int index,String object)
{
data.set(index, object);
notifyDataSetChanged();
}
public void clear()
{
data.clear();
notifyDataSetChanged();
}
public void remove(Object object)
{
data.remove(object);
notifyDataSetChanged();
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return data.size();
}
public void insert(String object,int c)
{
data.set(c, object);
notifyDataSetChanged();
}
#Override
public String getItem(int position) {
// TODO Auto-generated method stub
if(position >= 0 && position < data.size())
{
return data.get(position);
}
return null;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public static class ViewHolder{
public TextView text;
public ImageView image;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
ViewHolder holder;
if(convertView==null){
vi = inflater.inflate(R.layout.item,parent, false);
holder=new ViewHolder();
holder.text=(TextView)vi.findViewById(R.id.text);
holder.image=(ImageView)vi.findViewById(R.id.image);
vi.setTag(holder);
}
else
holder=(ViewHolder)vi.getTag();
holder.text.setText(data.get(position));
holder.image.setImageDrawable(activity.getResources().getDrawable(ItemIcon));
ImageButton btn_more = (ImageButton) vi.findViewById(R.id.more);
if(moreVis)
{
btn_more.setOnClickListener(new OnMoreClickListener(btn_more,position));
}
else
{
btn_more.setVisibility(View.GONE);
}
vi.setOnClickListener(new OnRowClickListener(vi,position));
return vi;
}
public abstract void OnRowClick(View mView, int position);
public abstract void OnMoreClick(View mView, int position);
private class OnRowClickListener implements OnClickListener{
private int mPosition;
private View mView;
OnRowClickListener(View view,int position){
mPosition = position;
mView = view;
}
#Override
public void onClick(View arg0) {
OnRowClick(mView,mPosition);
}
}
private class OnMoreClickListener implements OnClickListener{
private int mPosition;
private View mView;
OnMoreClickListener(View view,int position){
mPosition = position;
mView = view;
}
#Override
public void onClick(View arg0) {
OnMoreClick(mView,mPosition);
}
}
}
the debugger shows that only the size of data has been changed but none of its content. Do i miss something here???
some additional code:
public abstract class MYSCREEN extends ListView{
public abstract void Init();
public abstract void OnLoadFinished();
public abstract void OnRowClicked(int position);
public abstract void onCreateQuickAction(MYQUICKACTION action,int position);
public abstract void CreateOptionMenu(Menu menu);
public abstract boolean OptionsItemSelected(MenuItem item);
public MYLISTITEM adapter = null;
public static void StartupScreen(Activity current,Class<?> next)
{
Intent myIntent = new Intent(current,next);
current.startActivity(myIntent);
}
public MYSCREEN(Activity context,int Icon) {
super(context);
boolean moreisvis = true;
MYQUICKACTION canarybirdybirdy = new MYQUICKACTION(new View(context));
onCreateQuickAction(canarybirdybirdy,0);
if(canarybirdybirdy.anchor.getVisibility() != View.VISIBLE)
{
moreisvis = false;
}
adapter = new MYLISTITEM(context,Icon,moreisvis){
#Override
public void OnRowClick(View mView, int position) {
// TODO Auto-generated method stub
OnRowClicked(position);
}
#Override
public void OnMoreClick(View mView, int position) {
// TODO Auto-generated method stub
final MYQUICKACTION mQuickAction = new MYQUICKACTION(mView);
final ImageButton mMoreImage = (ImageButton) mView.findViewById(MY.views.R.id.more);
mMoreImage.setImageResource(MY.views.R.drawable.ic_list_more_selected);
onCreateQuickAction(mQuickAction,position);
mQuickAction.setAnimStyle(MYQUICKACTION.ANIM_AUTO);
mQuickAction.setOnDismissListener(new OnDismissListener() {
#Override
public void onDismiss() {
mMoreImage.setImageResource(MY.views.R.drawable.ic_list_more);
}
});
mQuickAction.show();
}
};
final ProgressDialog dialog = new ProgressDialog(context);
dialog.setMessage("loading...");
dialog.show();
new LOADER(){
#Override
public void RunThread() {
Init();
}
#Override
public void FinishLoad() {
dialog.dismiss();
OnLoadFinished();
}
}.Start();
}
public abstract class MYTHREAD extends AsyncTask<Void, Void, Void> {
public abstract void InitThread();
public abstract void RunThread();
public abstract void FinishThread();
#Override
protected Void doInBackground(Void... params) {
RunThread();
// TODO Auto-generated method stub
return null;
}
//ui stuff allowed
#Override
protected void onPreExecute() {
InitThread();
}
//ui stuff allowed
#Override
protected void onProgressUpdate(Void... value) {
super.onProgressUpdate(value);
}
//ui stuff allowed
#Override
protected void onPostExecute(final Void unused) {
FinishThread();
}
public void Start()
{
this.execute();
}
}
public abstract class LOADER extends MYTHREAD{
public abstract void FinishLoad();
#Override
public void InitThread() {
// TODO Auto-generated method stub
}
#Override
public void FinishThread() {
// TODO Auto-generated method stub
FinishLoad();
}
}}
and here is the function that gives me the headache.Its from one of MYSCREEN derived classes , oh and its also called from the search-buttons clickevent.
#Override
public void OnLoadFinished() {
// TODO Auto-generated method stub
SelectedTable = TabController.Instance.Clients[TabController.Instance.selectedtab ? 1 : 0].DbTablename;
adapter.clear();
TabController.Instance.Clients[TabController.Instance.selectedtab ? 1 : 0].MetaEntities(SelectedTable, true, new ClientCallBackHandler(){
#Override
public void StartCallBack() {
// TODO Auto-generated method stub
prgdialog.setMessage("connecting service...");
prgdialog.show();
}
#Override
public void EndCallBack(boolean success) {
// TODO Auto-generated method stub
if(success)
{
try{
ExceptionResponse except = (ExceptionResponse) this.response;
ab.setMessage(Html.fromHtml("<b><font color=#ff0000>" + except.Message));
ab.setPositiveButton("ok", null);
ab.show();
success = false;
}catch(Exception e)
{
MetadataEntitiesResponse resp = (MetadataEntitiesResponse) response;
if(resp.Entities[0] != null)
{
Ent = resp.Entities[0];
int i = 0;
//search for the first string in our database ...
for(AttributeMetaData Att : Ent.Attributes)
{
if(Att.Type.contentEquals("string"))
{
SelectedAttribute = i;
break;
}
i++;
}
StartQuery(0); //here the adapter gets filled with info
}
}
}
}
});
}
private void StartQuery(int page)
{
if(currentpage != -1)
{
nextpage = page;
return;
}
Query query = new Query();
query.EntityName = Ent.Name;
if(SearchFilter != null)
{
query.Filter = new Filter();
query.Filter.Filters = SearchFilter;
query.Filter.FilterOperator = Filter.E_FilterOperator.And;
}
query.Columns = new AllColumns();
query.Limit = new Limit();
query.Limit.Count = 15;
Order order = new Order();
order.OrderType = Order.OrderTypeE.Ascending;
order.AttributeName = Ent.Attributes[SelectedAttribute].Name;
query.Orders = new Order[] {order};
currentpage = query.Limit.Page = page;
TabController.Instance.Clients[TabController.Instance.selectedtab ? 1 : 0].RetrieveMultiple(query, new ClientCallBackHandler(){
#Override
public void StartCallBack() {
// TODO Auto-generated method stub
}
#Override
public void EndCallBack(boolean success) {
// TODO Auto-generated method stub
try{
ExceptionResponse except = (ExceptionResponse) this.response;
ab.setMessage(Html.fromHtml("<b><font color=#ff0000>" + except.Message));
ab.setPositiveButton("ok", null);
ab.show();
success = false;
}catch(Exception e)
{
RetrieveMultipleResponse rmResp = (RetrieveMultipleResponse) this.response;
if(adapter.getCount() == 0)
{
for(int i = 0; i< rmResp.TotalRecords;i++)
{
prgdialog.setMessage( ((int) (i/rmResp.TotalRecords * 100)) + "%");
adapter.add("connecting...");
}
prgdialog.dismiss();
}
int i = 0;
for(Entity ent : rmResp.Entities)
{
adapter.replace(currentpage*15+i, ent.Properties[SelectedAttribute].ToString());
i++;
}
if(currentpage == nextpage)
{
nextpage = -1;
}
else
{
StartQuery(nextpage);
}
currentpage = -1;
}
}
});
}
i tried this code..
in oncreate() of where we are creating the CustomListView Adapter, call a function.
adapter.clear();
on the CustomListViewAdapter class create a function as clear
public void clear() {
// TODO Auto-generated method stub
movieItems.clear();
}
where movieItems is the name of the ListView
Call notifyDataSetChanged() instead.
In general you use notifyDataSetInvalidated() if item properties change, and notifyDataSetChanged() if items themselves change (i.e. items are removed or added).