I'm working on a homework planner app, and I'm looking for a way to display only certain elements in an ArrayList that holds Task objects. After the user clicks on a course from a list of course titles, the list of tasks that pertain to that course should be displayed. Currently, it shows a list of all tasks, no matter which course has been selected. Each Task object stores the course that it belongs to, in a field called mBelongsToCourse. I would like to be able to filter the ArrayList of all tasks that is used in my TaskAdapter to only show the tasks which belong to a specific course, but all my attempts have been fruitless.
Below is my TaskListFragment Class, which includes the TaskAdapter:
public class TaskListFragment extends ListFragment {
private ArrayList<Task> mTasks;
private static String courseName;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
courseName = getActivity().getIntent().getStringExtra("name");
getActivity().setTitle(courseName);
mTasks = TaskLab.get(getActivity()).getTasks();
TaskAdapter adapter = new TaskAdapter(mTasks);
setListAdapter(adapter);
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
//Get the Task from the adapter
Task t = ((TaskAdapter)getListAdapter()).getItem(position);
// Start TaskActivity for this task
Intent i = new Intent(getActivity(), TaskActivity.class);
i.putExtra(TaskFragment.EXTRA_TASK_ID, t.getId());
startActivity(i);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.fragment_task_list, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_item_new_task:
Task task = new Task();
task.setBelongsToCourse(courseName);
TaskLab.get(getActivity()).addTask(task);
Intent i = new Intent(getActivity(), TaskActivity.class);
i.putExtra(TaskFragment.EXTRA_TASK_ID, task.getId());
//i.putExtra("cn", task.getBelongsToCourse());
startActivityForResult(i, 0);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
getActivity().getMenuInflater().inflate(R.menu.task_list_item_context, menu);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent,
Bundle savedInstanceState) {
View v = super.onCreateView(inflater, parent, savedInstanceState);
ListView listView = (ListView)v.findViewById(android.R.id.list);
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {
public void onItemCheckedStateChanged(ActionMode mode, int position,
long id, boolean checked) {
// Required, but not used in this implementation
}
// ActionMode.Callback methods
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.task_list_item_context, menu);
return true;
}
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
// Required, but not used in this implementation
}
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_item_delete_task:
TaskAdapter adapter = (TaskAdapter)getListAdapter();
TaskLab taskLab = TaskLab.get(getActivity());
for (int i = adapter.getCount() - 1; i >= 0; i--) {
if (getListView().isItemChecked(i)) {
taskLab.deleteTask(adapter.getItem(i));
}
}
mode.finish();
adapter.notifyDataSetChanged();
return true;
default:
return false;
}
}
public void onDestroyActionMode(ActionMode mode) {
// Required, but not used in this implementation
}
});
return v;
}
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo)item.getMenuInfo();
int position = info.position;
TaskAdapter adapter = (TaskAdapter)getListAdapter();
Task task = adapter.getItem(position);
switch (item.getItemId()) {
case R.id.menu_item_delete_task:
TaskLab.get(getActivity()).deleteTask(task);
adapter.notifyDataSetChanged();
return true;
}
return super.onContextItemSelected(item);
}
#Override
public void onResume() {
super.onResume();
((TaskAdapter)getListAdapter()).notifyDataSetChanged();
}
private class TaskAdapter extends ArrayAdapter<Task> {
public TaskAdapter(ArrayList<Task> tasks) {
super(getActivity(), 0, tasks);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// If we weren't given a view, inflate one
if (convertView == null) {
convertView = getActivity().getLayoutInflater()
.inflate(R.layout.list_item_task, null);
}
// Configure the view for this Task
Task t = getItem(position);
TextView titleTextView =
(TextView)convertView.findViewById(R.id.task_list_item_titleTextView);
titleTextView.setText(t.getTitle());
TextView dateTextView =
(TextView)convertView.findViewById(R.id.task_list_item_dateTextView);
dateTextView.setText(t.getDate().toString());
CheckBox completedCheckBox =
(CheckBox)convertView.findViewById(R.id.task_list_item_completedCheckBox);
completedCheckBox.setChecked(t.isCompleted());
return convertView;
}
}
}
Any help would be greatly appreciated.
EDIT: I've followed the advice of Ravind Maurya and Embattled Swag and updated my TaskAdapter:
private class TaskAdapter extends ArrayAdapter<Task> implements Filterable {
private ArrayList<Task> taskList;
private Filter taskFilter;
public TaskAdapter(ArrayList<Task> tasks) {
super(getActivity(), 0, tasks);
this.taskList = tasks;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// If we weren't given a view, inflate one
if (convertView == null) {
convertView = getActivity().getLayoutInflater()
.inflate(R.layout.list_item_task, null);
}
// Configure the view for this Task
Task t = getItem(position);
TextView titleTextView =
(TextView)convertView.findViewById(R.id.task_list_item_titleTextView);
titleTextView.setText(t.getTitle());
TextView dateTextView =
(TextView)convertView.findViewById(R.id.task_list_item_dateTextView);
dateTextView.setText(t.getDate().toString());
CheckBox completedCheckBox =
(CheckBox)convertView.findViewById(R.id.task_list_item_completedCheckBox);
completedCheckBox.setChecked(t.isCompleted());
return convertView;
}
#Override
public Filter getFilter() {
if (taskFilter == null)
taskFilter = new TaskFilter();
return taskFilter;
}
private class TaskFilter extends Filter {
#Override
protected FilterResults performFiltering (CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint == null | constraint.length() == 0) {
results.values = taskList;
results.count = taskList.size();
} else {
ArrayList<Task> newTaskList = new ArrayList<Task>();
for (Task t : taskList) {
if (t.getBelongsToCourse().toUpperCase().startsWith(constraint.toString().toUpperCase())) {
newTaskList.add(t);
}
}
results.values = newTaskList;
results.count = newTaskList.size();
} return results;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
// Now we have to inform the adapter about the new list filtered
if (results.count == 0)
notifyDataSetInvalidated();
else {
taskList = (ArrayList<Task>)results.values;
notifyDataSetChanged();
}
}
}
}
Now the problem I have is I don't know where to call .getFilter().filter(courseName) in order to filter the ArrayList.
I followed this example literally yesterday to come up with a solid filter: http://www.survivingwithandroid.com/2012/10/android-listview-custom-filter-and.html
However; this example doesn't cover the case where you use the backspace and therefore the listview has to repopulate. You can follow the actual source code for the generic Filter here (it's at the bottom...essentially you'll just create a copy and then reduce the items of one of the lists): http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4/android/widget/ArrayAdapter.java#ArrayAdapter.0mOriginalValues
Related
I want filter the recycleView by searchView.
I add xml file to menu.
When the app run she stop when the fragment open.
When I put break point I found the problem in line: SearchView searchView = (SearchView) searchItem.getActionView() - in method onCreateOptionsMenu.
why this happening? (the addapter create in fragment)
In xml menu I changed to
app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="android.support.v7.widget.SearchView"/>
#SuppressLint("ValidFragment")
public class AvailableDrivesFragment extends Fragment {
public RecyclerView drivesRecyclerView;
public LinearLayout details;
public List<Drive> drives = new ArrayList<>();
public TextView textDetails;
public Button buttonChoose;
IDataBase fb = FactoryDataBase.getDataBase();
private DrivesRecycleViewAdapter adapter;
private Menu menu;
Driver driver;
#SuppressLint("ValidFragment")
AvailableDrivesFragment(Driver e) {
this.driver = e;
}
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_available_drives, container, false);
textDetails = v.findViewById(R.id.text_details);
details = v.findViewById(R.id.linear_details);
details.setVisibility(View.GONE);
getActivity().setTitle("Available Drives");
drivesRecyclerView = v.findViewById(R.id.my_list);
drivesRecyclerView.setHasFixedSize(true);
drivesRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
adapter = new DrivesRecycleViewAdapter();
drives = fb.getAvailableDrives();
drivesRecyclerView.setAdapter(adapter);
setHasOptionsMenu(true);
return v;
}
#Override
public void onDestroy() {
Firebase_DBManager.stopNotifyToDriveList();
super.onDestroy();
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
inflater.inflate(R.menu.search, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) searchItem.getActionView();//here stop working
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
try {
adapter.getFilter().filter(newText);
}
catch (Exception r) {
r.printStackTrace();
}
return false;
}
});
}
public class DrivesRecycleViewAdapter extends RecyclerView.Adapter<DrivesRecycleViewAdapter.DriveViewHolder> implements Filterable
{
public List<Drive> drivefull;
public DrivesRecycleViewAdapter() {
this.drivefull = new ArrayList<>(drives);
;
}
#Override
public DriveViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(getActivity()).inflate(R.layout.item_drive, parent, false);
return new DriveViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull DriveViewHolder holder, int position) {
Drive drive = drives.get(position);
holder.nameTextView.setText(drive.getName());
holder.nameTextView.setTextSize(20);
holder.phoneTextView.setText(drive.getStartAddress());
holder.phoneTextView.setTextSize(16);
}
#Override
public int getItemCount() {
return drives.size();
}
#Override
public Filter getFilter() {
return filter;
}
public Filter filter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
List<Drive> filteredList = new ArrayList<>();//new list that contained only filtered items
if (constraint == null || constraint.length() == 0)//we what to show all the results becuse we don't what filtering
{
filteredList.addAll(drivefull);
} else { //we what to filter the list
String filterPattern = constraint.toString().toLowerCase().trim(); // sting that takes the input
for (Drive item : drivefull) {
if (item.getName().toLowerCase().contains((filterPattern))) {
filteredList.add(item);
}
}
}
FilterResults results = new FilterResults();
results.values = filteredList;
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
drives.clear();
drives.addAll((List) results.values);
notifyDataSetChanged();
}
};
class DriveViewHolder extends RecyclerView.ViewHolder {
TextView phoneTextView;
TextView nameTextView;
public DriveViewHolder(final View itemView) {
super(itemView);
phoneTextView = itemView.findViewById(R.id.phone_item_drive);
nameTextView = itemView.findViewById(R.id.name_item_drive);
itemView.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
menu.setHeaderTitle("Select Action");
MenuItem detailm = menu.add(Menu.NONE, 1, 1, "view details");
detailm.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
Drive drive = drives.get(getAdapterPosition());
textDetails.setText(drive.toString());
details.setVisibility(View.VISIBLE);
return true;
}
});
MenuItem addDrive = menu.add(Menu.NONE, 1, 1, "take drive");
addDrive.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
final Drive drive = drives.get(getAdapterPosition());
fb.changeStatus(drive.getId(), driver, DriveStatus.TREATMENT, new IDataBase.Action() {
#Override
public void onSuccess() {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage("The drive is in your care!")
.setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
String mail = drive.getEmail();
String[] mails = mail.split(",");
Intent in = new Intent(Intent.ACTION_SEND);
in.putExtra(Intent.EXTRA_EMAIL, mails);
in.putExtra(Intent.EXTRA_SUBJECT, "get taxi");
in.putExtra(Intent.EXTRA_TEXT, "taxi will coming to you in few minutes");
in.setType("message/rfc822");
startActivity(Intent.createChooser(in, "choose email"));
}
});
AlertDialog alert = builder.create();
alert.show();
drives.remove(getAdapterPosition());
drivesRecyclerView.getAdapter().notifyDataSetChanged();
}
#Override
public void onFailure(Exception exception) {
Toast.makeText(getActivity(), "הלקיחה נכשלה", Toast.LENGTH_LONG).show();
}
#Override
public void onProgress(String status, double percent) {
;
}
});
return true;
}
});
}
});
}
}
}
}
I have a list view with 100 items. On creating the ListView shows first 10 items. If the user clicks ShowRemainingItems option from the menu, I want to display items from 11 to 100. I tried with the below code, but it did not work.The list view is not getting lodaed on clicking the menu. Can some one help?
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Init user list
ListView list = (ListView) this.findViewById(R.id.dataList);
this.listAdapter = new DataListAdapter(this, R.layout.list_view_cell);
list.setAdapter(listAdapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.options_menu,menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.ShowRemainingItems) {
Toast.makeText(this,"refresh clicked",Toast.LENGTH_SHORT).show();
listAdapter.clear();
// Update the 'listData' according to your preferences like displaying the items from 11 to 100
// Notify the adapter about the change
updateDataList();
listAdapter.notifyDataSetChanged();
}
return super.onOptionsItemSelected(item);
}
public void updateDataList() {
Toast.makeText(this,"Update data list called",Toast.LENGTH_SHORT).show();
ListView list = (ListView) this.findViewById(R.id.dataList);
list.setSelectionFromTop(11,12);
Toast.makeText(this,"setSelectionFromTop selected",Toast.LENGTH_SHORT).show();
}
And the Datalistadapter.java
public class DataListAdapter extends ArrayAdapter {
private Context context;
private ArrayList<User> userList;
private int layoutRessource;
public ArrayList<User> getUserList() {
return userList;
}
public DataListAdapter(Context ctx, int layoutResourceId) {
super(ctx, layoutResourceId);
this.userList = new ArrayList<User>();
this.layoutRessource = layoutResourceId;
this.context = ctx;
}
public void addUser(User usr) {
this.userList.add(usr);
}
public void removeUser(String usrId) {
for (User usr : userList) {
if (usr.getId().equals(usrId)) {
this.userList.remove(usr);
}
}
}
#Override
public void clear() {
super.clear();
if(userList != null)
userList.clear();
}
#Override
public int getCount() {
//return this.userList.size();
return Math.min(10, this.userList.size());
}
#Override
public User getItem(int position) {
return this.userList.get(position);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
LayoutInflater li = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = li.inflate(this.layoutRessource, null);
}
// Get row user
User currentUser = getItem(position);
Log.d(TAG, "SIZE: " + this.userList.get(position));
// Id
TextView idLabel = (TextView) row.findViewById(R.id.id);
return row;
}
}
You need to first clear the update the dataset of the adapter and then then notify the adapter about the change so that it can update the UI accordingly. Also don't fetch the ListView each time you are using it and set the Adapter to it, instead make it as global.
ListView list;
ArrayList<String> listData = new ArrayList<String>();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Init user list
list = (ListView) this.findViewById(R.id.dataList);
this.listAdapter = new DataListAdapter(this, R.layout.list_view_cell, listData);
list.setAdapter(listAdapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.options_menu,menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.ShowRemainingItems)
{
Toast.makeText(this,"refresh clicked",Toast.LENGTH_SHORT).show();
listData.clear();
// Update the 'listData' according to your preferences like displaying the items from 11 to 100
updateDataList();
// Notify the adapter about the change
listAdapter.notifyDataSetChanged();
}
else if(id == R.id.action_settings)
{
Toast.makeText(this,"Settings clicked",Toast.LENGTH_SHORT).show();
}
return super.onOptionsItemSelected(item);
}
You have several problems in your code. However, I took the responsibility of fixing and here's the modified code. Please note that the code is not tested, so please modify as per your further requirement.
I have added comments where you have done mistakes. Please check them carefully. Thanks.
private ArrayList<User> userList;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initialize the userList here
userList = new ArrayList<User>();
userList = getFirst10Items();
// Initialize ListView and pass the userList into your adapter
ListView list = (ListView) this.findViewById(R.id.dataList);
this.listAdapter = new DataListAdapter(this, R.layout.list_view_cell, userList);
list.setAdapter(listAdapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.options_menu,menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.ShowRemainingItems) {
// Remove the following. This will not be needed
// listAdapter.clear();
updateDataList();
// Not necessary. As the updateDataList has already the notifyDataSetChanged command
// listAdapter.notifyDataSetChanged();
}
return super.onOptionsItemSelected(item);
}
public void updateDataList() {
// Do not initiate the ListView again. Just use the ListView that is already created.
// ListView list = (ListView) this.findViewById(R.id.dataList);
// This is not the way of selecting items in your ListView. I think your knowledge of how adapter works is wanting
// list.setSelectionFromTop(11,12);
// Here's the new implementation.
ArrayList<User> userListFor11To100 = getTheRemainingUsers();
userList.addAll(userListFor11To100);
listAdapter.notifyDataSetChanged();
}
public List<User> getTheRemainingUsers() {
// You need to implement the getTheRemainingUsers function yourself which will get the data for the position 11 to 100 in the ListView
// Just use userList.add(user) function instead of using listAdapter.addUser() function
}
public List<User> getFirst10Items() {
// You need to implement the getFirst10Items function yourself which will get the data for the position 0 to 10 in the ListView
// Just use userList.add(user) function instead of using listAdapter.addUser() function
}
Now you need to modify your adapter like the following.
public class DataListAdapter extends ArrayAdapter {
private Context context;
private ArrayList<User> userList;
private int layoutRessource;
// Modify the constructor to get the userList passed from the activity to the adapter.
public DataListAdapter(Context ctx, int layoutResourceId, ArrayList<User> userList) {
super(ctx, layoutResourceId);
this.userList = userList;
this.layoutRessource = layoutResourceId;
this.context = ctx;
}
public void addUser(User usr) {
this.userList.add(usr);
// Call the notifyDataSetChanged after adding each user to the list
notifyDataSetChanged();
}
public void removeUser(String usrId) {
for (User usr : userList) {
if (usr.getId().equals(usrId)) {
this.userList.remove(usr);
break;
}
}
// Call the notifyDataSetChanged after removing each user to the list
notifyDataSetChanged();
}
#Override
public void clear() {
super.clear();
if(userList != null) {
userList.clear();
// Call the notifyDataSetChanged after removing all user from the list
notifyDataSetChanged();
}
}
#Override
public int getCount() {
return this.userList.size();
// The following statement is wrong!! Return the actual size of the list all the time.
// return Math.min(10, this.userList.size());
}
#Override
public User getItem(int position) {
return this.userList.get(position);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
LayoutInflater li = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = li.inflate(this.layoutRessource, null);
}
// Get row user
User currentUser = getItem(position);
Log.d(TAG, "SIZE: " + this.userList.get(position));
// Id
TextView idLabel = (TextView) row.findViewById(R.id.id);
// Set something to the TextView. Now its showing nothing.
idLabel.setText(currentUser.getId());
return row;
}
}
I am trying to implement MultiChoiceModeListener for select multiple item from a ListView. My current progress is shown below. But it doesn't working. It has no action on even long press. is any thing missed in my code or anything wrong? Any help will be greatly appreciated.
public class FragmentFavorite extends Fragment {
ListView lvFavoriteItems;
Activity mActivity = null;
Context mContext;
ArrayList<String> names = new ArrayList<>(Arrays.asList("My name is a", "My name is b",
"My name is c", "My name is d", "My name is e", "My name is f"));
ArrayList<String> phone = new ArrayList<>(Arrays.asList("9895653263", "9895653264", "9895653265",
"9895653266", "9895653267", "9895653267"));
#Override
public void onAttach(Context context) {
super.onAttach(context);
if(mActivity == null) {
this.mActivity = getActivity();
}
this.mContext = context;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.favorite_list, container, false);
lvFavoriteItems = (ListView) root.findViewById(R.id.lv_item_list);
FavoriteAdapter fav = new FavoriteAdapter();
lvFavoriteItems.setAdapter(fav);
lvFavoriteItems.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
lvFavoriteItems.setMultiChoiceModeListener(new FavMultiChoiceModeListener());
return root;
}
private class FavoriteAdapter extends BaseAdapter {
#Override
public int getCount() {
return names.size();
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
View listItem;
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
listItem = inflater.inflate(R.layout.contact_item_2_line, null);
} else {
listItem = convertView;
}
TextView tv1 = (TextView) listItem.findViewById(R.id.tv_item_name);
tv1.setText(names.get(position));
TextView tv2 = (TextView) listItem.findViewById(R.id.tv_phone);
tv2.setText(phone.get(position));
listItem.setId(position);
return listItem;
} }
private class FavMultiChoiceModeListener implements ListView.MultiChoiceModeListener {
#Override
public void onItemCheckedStateChanged(ActionMode mode, int i, long l, boolean b) {
final int checkedCount = lvFavoriteItems.getCheckedItemCount();
mode.setSubtitle("" + checkedCount + " items selected ");
}
#Override
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
MenuInflater inflater = mActivity.getMenuInflater();
inflater.inflate(R.menu.selection_menu, menu);
actionMode.setTitle("Select Items");
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
return true;
}
#Override
public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
Toast.makeText(mActivity, "Clicked " + menuItem.getTitle(),
Toast.LENGTH_SHORT).show();
return true;
}
#Override
public void onDestroyActionMode(ActionMode actionMode) {
}
}
}
Since you're extending from BaseAdapter, you might need to call convertView.setLongClickable(true) in your getView method.
As the topic's name mentions, I'm facing a problem when I'm trying to implement live ListView filtering, when user enters some text in search bar, which is located in the Action Bar.
P.S. I didn't even hav Log.i("Nomad", "onQueryTextChange") in onQueryTextChange() printed in the log, when I'm debugging the application :/
AllLists.java
public class AllLists extends Fragment implements SearchView.OnQueryTextListener{
private TypedArray navMenuIcons;
private Context context;
private int position = 0;
private String location;
private List<Item> items = new ArrayList<Item>();
private ListView listView;
private CustomListAdapter adapter;
private SearchView mSearchView;
public AllLists(Context context) {
this.context = context;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.alllists, container, false);
View header = inflater.inflate(R.layout.list_header, null);
// View list_view = inflater.inflate(R.layout.list_item, null);
ImageView image = (ImageView) header.findViewById(R.id.small_icon);
header.setClickable(false);
// ImageView logo = (ImageView) list_view.findViewById(R.id.image);
navMenuIcons = getResources().obtainTypedArray(R.array.nav_drawer_icons);
Bundle bundle = getArguments();
position = bundle.getInt("position");
location = bundle.getString("location");
image.setImageDrawable(navMenuIcons.getDrawable(position));
DatabaseHandler db = new DatabaseHandler(context);
items = db.getAllItems(location);
listView = (ListView) rootView.findViewById(R.id.list);
adapter = new CustomListAdapter(context, items);
listView.setAdapter(adapter);
listView.addHeaderView(header);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (location.equals("accommodation") || location.equals("eat") || location.equals("events")
|| location.equals("entertainment") || location.equals("places") || location.equals("cinema")) {
Intent i = new Intent(context, ItemScreen.class);
i.putExtra("position", position - 1);
i.putExtra("location", location);
startActivity(i);
}
}
});
setHasOptionsMenu(true);
return rootView;
}
/*SearchView.OnQueryTextListener(new SearchView.OnQueryTextListener){
}*/
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.main, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
mSearchView = (SearchView) MenuItemCompat.getActionView(searchItem);
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String s) {
return false;
}
#Override
public boolean onQueryTextChange(String s) {
adapter.getFilter().filter(s);
return false;
}
});
}
#Override
public boolean onQueryTextChange(String s) {
Log.i("Nomad", "onQueryTextChange");
adapter.getFilter().filter(s);
return false;
}
#Override
public boolean onQueryTextSubmit(String s) {
return false;
}
}
CustomListAdapter.java
public class CustomListAdapter extends BaseAdapter {
private Context context;
private List<Item> items;
private LayoutInflater inflater;
ImageLoader imageLoader = AppController.getInstance().getImageLoader();
private List<Item> filteredData;
public CustomListAdapter(Context context, List<Item> items) {
this.context = context;
this.items = items;
}
#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) {
if (inflater == null)
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
convertView = inflater.inflate(R.layout.list_item, null);
if (imageLoader == null)
imageLoader = AppController.getInstance().getImageLoader();
NetworkImageView image = (NetworkImageView) convertView.findViewById(R.id.image);
TextView name = (TextView) convertView.findViewById(R.id.name);
TextView type = (TextView) convertView.findViewById(R.id.type);
Item i = items.get(position);
// Log.d("FOTO linkas: " + i.getName() + " ", i.getIcon());
if (i.getIcon().contains("http")) {
// Log.d("suveike: ", i.getIcon());
image.setImageUrl(i.getIcon(), imageLoader);
}/*else if(items.get(0).getName().contains("taksi")) {
Log.d("suveike: ", "else if");
image.setImageResource(R.drawable.logo);
}*/ else
image.setImageResource(R.drawable.logo);
name.setText(i.getName());
type.setText(i.getType());
return convertView;
}
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
FilterResults results = new FilterResults();
if (charSequence == null || charSequence.length() == 0) {
results.values = items;
results.count = items.size();
} else {
List<Item> filtered_items = new ArrayList<Item>();
for (int i = 0; i < items.size(); i++) {
if (items.get(i).getName().contains(charSequence))
filtered_items.add(items.get(i));
}
results.values = filtered_items;
results.count = filtered_items.size();
}
return results;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
filteredData = (List<Item>) filterResults.values;
notifyDataSetChanged();
}
};
}
}
You have to type listView.setAdapter(adapter) after adapter.getFilter().filter(s) in onQueryTextChange. That will refresh the listView.
Well then, you can try this..Don't do implements SearchView.onQueryTextChangeListner..
Instead in onCreateView, write the following
mSearchView.setOnQueryTextListener(new OnQueryTextListener()
{
#Override
public boolean onQueryTextSubmit(String query) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
//your code here
return false;
}
});
I'm trying to convert my entire ListFragment class into a Fragment class with a ListView added to it.
Call this class HomeworkListFragment. I changed the extension from ListFragment to Fragment:
As a result I have created the following:
public class HomeworkListFragment extends Fragment{
public static final String TAG = "HomeworkListFragment";
public ListView mListView;
public HomeworkAdapter mAdapter;
private ArrayList<HomeworkObject> mCrimes;
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
getActivity().setTitle(R.string.homework_title);
mCrimes = HomeworkLab.get(getActivity()).getHomework();
mAdapter = new HomeworkAdapter(mCrimes);
mListView.setAdapter(mAdapter);
setRetainInstance(true);
}
#TargetApi(11)
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState){
View v = super.onCreateView(inflater,parent,savedInstanceState);
mListView = (ListView)v.findViewById(android.R.id.list);
mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
mListView.setMultiChoiceModeListener(new MultiChoiceModeListener(){
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()){
case R.id.menu_item_delete_homework:
HomeworkLab homeworkLab = HomeworkLab.get(getActivity());
for (int i = mAdapter.getCount() - 1;i>=0;i--){
//if (mListView.getListView().isItemChecked(i)){
//homeworkLab.deleteHomework(mAdapter.getItem(i));
//}
}
mode.finish();
mAdapter.notifyDataSetChanged();
return true;
default:
return false;
}
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
//ActionMode.callback Methods
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.homework_list_item_context, menu);
return true;
}
#Override
public void onDestroyActionMode(ActionMode arg0) {
//not used here
}
#Override
public boolean onPrepareActionMode(ActionMode arg0, Menu arg1) {
//not used here
return false;
}
#Override
public void onItemCheckedStateChanged(ActionMode arg0,
int arg1, long arg2, boolean arg3) {
//not used here
}
});
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
HomeworkObject c = mAdapter.getItem(position);
//Start CrimeActivity
//Intent i = new Intent(getActivity(), CrimeActivity.class);
Intent i = new Intent(getActivity(), HomeworkPagerActivity.class);
i.putExtra(HomeworkFragment.EXTRA_HOMEWORK_ID, c.getId());
startActivity(i);
}
});
return v;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){
super.onCreateOptionsMenu(menu,inflater);
inflater.inflate(R.menu.fragment_homework_list, menu);
}
#TargetApi(11)
#Override
public boolean onOptionsItemSelected(MenuItem item){
switch(item.getItemId()){
case R.id.menu_item_new_homework:
HomeworkObject homework = new HomeworkObject();
homework.setTitle("");
HomeworkLab.get(getActivity()).addHomework(homework);
Intent i = new Intent(getActivity(),HomeworkPagerActivity.class);
i.putExtra(HomeworkFragment.EXTRA_HOMEWORK_ID, homework.getId());
startActivityForResult(i,0);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
getActivity().getMenuInflater().inflate(R.menu.homework_list_item_context, menu);
}
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo)item.getMenuInfo();
int position = info.position;
HomeworkObject h = mAdapter.getItem(position);
switch (item.getItemId()) {
case R.id.menu_item_delete_homework:
HomeworkLab.get(getActivity()).deleteHomework(h);
mAdapter.notifyDataSetChanged();
return true;
}
return super.onContextItemSelected(item);
}
#Override
public void onResume() {
super.onResume();
mAdapter.notifyDataSetChanged();
mCrimes = HomeworkLab.get(getActivity()).getHomework();//update list
}
#Override
public void onPause(){
super.onPause();
HomeworkLab.get(getActivity()).saveHomework();
}
/*#Override
public void onListItemClick(ListView l, View v, int position, long id){
HomeworkObject c = ((HomeworkAdapter)getListAdapter()).getItem(position);
//Start CrimeActivity
//Intent i = new Intent(getActivity(), CrimeActivity.class);
Intent i = new Intent(getActivity(), HomeworkPagerActivity.class);
i.putExtra(HomeworkFragment.EXTRA_HOMEWORK_ID, c.getId());
startActivity(i);
}*/
private class HomeworkAdapter extends ArrayAdapter<HomeworkObject>{
public HomeworkAdapter(ArrayList<HomeworkObject> crimes){
super(getActivity(), 0, crimes);
}
#SuppressLint("SimpleDateFormat")
#Override
public View getView(int position, View convertView, ViewGroup parent){
if (convertView == null){
convertView = getActivity().getLayoutInflater().inflate(R.layout.list_item_homework, null);
}
HomeworkObject c = getItem(position);
TextView titleTextView = (TextView)convertView.findViewById(R.id.homework_list_item_titleTextView);
titleTextView.setText(c.getTitle());
TextView dateTextView = (TextView)convertView.findViewById(R.id.homework_list_item_dateTextView);
DateFormat df = new SimpleDateFormat("EEEE, d MMMM yyyy");
String reportDate = df.format(c.getDate());
dateTextView.setText(reportDate);
//dateTextView.setText(c.getDate().toString());
CheckBox solvedCheckBox = (CheckBox)convertView.findViewById(R.id.homework_list_item_solvedCheckBox);
solvedCheckBox.setChecked(c.isSolved());
return convertView;
}
}
}
As far as I can tell there's an error in the onCreateView method with some null pointer error but I can't make heads or tails of this issue.
I recently picked up Android after moving from iOS so I'm pretty new to this. Any explanation could help a lot!
problem:
mListView = (ListView)v.findViewById(android.R.id.list);
The android.R.id.list is only bounded to the ListFragment not in Fragment and that is why it is null.
as the documentation for ListFragment:
ListFragment has a default layout that consists of a single list view.
However, if you desire, you can customize the fragment layout by returning
your own view hierarchy from onCreateView(LayoutInflater, ViewGroup, Bundle).
To do this, your view hierarchy must contain a ListView object with the
id "#android:id/list" (or list if it's in code)
Solution:
You need to inflate a view in your fragment and create a layout with ListView and use the created ID of the ListView instead of android.R.id.list
Use this instead:
#TargetApi(11)
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState){
super.onCreateView(inflater,parent,savedInstanceState);
View v = inflater.inflate(R.layout.my_fragment_layout, parent, false);
mListView = (ListView)v.findViewById(android.R.id.list);
mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
mListView.setMultiChoiceModeListener(new MultiChoiceModeListener(){
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()){
case R.id.menu_item_delete_homework:
HomeworkLab homeworkLab = HomeworkLab.get(getActivity());
for (int i = mAdapter.getCount() - 1;i>=0;i--){
//if (mListView.getListView().isItemChecked(i)){
//homeworkLab.deleteHomework(mAdapter.getItem(i));
//}
}
mode.finish();
mAdapter.notifyDataSetChanged();
return true;
default:
return false;
}
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
//ActionMode.callback Methods
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.homework_list_item_context, menu);
return true;
}
#Override
public void onDestroyActionMode(ActionMode arg0) {
//not used here
}
#Override
public boolean onPrepareActionMode(ActionMode arg0, Menu arg1) {
//not used here
return false;
}
#Override
public void onItemCheckedStateChanged(ActionMode arg0,
int arg1, long arg2, boolean arg3) {
//not used here
}
});
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
HomeworkObject c = mAdapter.getItem(position);
//Start CrimeActivity
//Intent i = new Intent(getActivity(), CrimeActivity.class);
Intent i = new Intent(getActivity(), HomeworkPagerActivity.class);
i.putExtra(HomeworkFragment.EXTRA_HOMEWORK_ID, c.getId());
startActivity(i);
}
});
return v;
}