I'm in an Android project.
I want to show a AlertDialog on which the user can pick one item (about 100 items, it's dynamic). I want to add the possibility of searching also.
My real problem is that it seems I can't change the items once the Dialog is created.
The creation code:
// The List with the beaches with radio buttons, single choice!
public void showBeachesDialog(final Activity context, boolean isFromZonas)
{
AlertDialog.Builder builder = new AlertDialog.Builder(context);
searchAdapter = new SearchDialogAdapater(orderedBeaches, orderedBeachesIds, context);
builder.setSingleChoiceItems(searchAdapter, -1, new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
index = which;
if (!((AlertDialog) dialog).getButton(AlertDialog.BUTTON_POSITIVE).isEnabled())
((AlertDialog) dialog).getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(true);
}
});
DialogOkOnClickListener listener = new DialogOkOnClickListener(context, isFromZonas);
builder.setPositiveButton(R.string.searchOK, listener);
builder.setNegativeButton(R.string.cancelar, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
// User cancelled the dialog: nothing happens
}
});
builder.setIcon(context.getResources().getDrawable(R.drawable.icon_beach));
builder.setTitle(StaticUtils.DIALOG_TITLE);
View dialogView = context.getLayoutInflater().inflate(R.layout.dialog_beaches, null);
SearchView searchView = (SearchView)dialogView.findViewById(R.id.search_beach);
searchView.setOnQueryTextListener(new SearchQueryListener(searchAdapter));
builder.setView(dialogView);
AlertDialog dialog = builder.create();
dialog.show();
dialog.getButton(Dialog.BUTTON_POSITIVE).setEnabled(false);
}
So, now I have the dialog with all the elements I want (the SearchDialogAdapater is fine).
The DialogOnClickListener is also working.
The search view is appearing on the dialog, and my SearchQueryListener is working perfectly, so I won't post here the code, but in Debug I can see that if I type "d" the elements without the "d" are filtered out.
Now I would like to not throw away all the code and find a way to change the items of the dialog without showing a new one...
Sorry for long question and if there is a obvious way I am missing...
Thank you all.
I solved this using a class that implements 4 interfaces so it can handles everything that I want.
The code is now like this, hope it's useful to someone who want to make its own Dialog with personalized search.
public void showBeachesDialog(final Activity context, boolean isFromZonas)
{
AlertDialog.Builder builder = new AlertDialog.Builder(context);
searchAdapter = new SearchDialogAdapater
(orderedBeaches, orderedBeachesIds, context, isFromZonas);
builder.setSingleChoiceItems(searchAdapter, -1, null);
builder.setPositiveButton(R.string.searchOK, searchAdapter);
builder.setNegativeButton(R.string.cancelar, null);
builder.setIcon(context.getResources().getDrawable(R.drawable.icon_beach));
builder.setTitle(StaticUtils.DIALOG_TITLE);
View dialogView = context.getLayoutInflater().inflate
(R.layout.dialog_beaches, null);
SearchView searchView = SearchView)dialogView.findViewById
(R.id.search_beach);
searchView.setOnQueryTextListener(searchAdapter);
builder.setView(dialogView);
AlertDialog dialog = builder.create();
dialog.show();
dialog.getListView().setOnItemClickListener(searchAdapter);
searchAdapter.setDialog(dialog);
dialog.getButton(Dialog.BUTTON_POSITIVE).setEnabled(false);
}
The orderedBeaches and orderedBeachesIds are String[] and int[], my data to display.
Below is my adapter which uses a stack to handle the items available at any moment of the searching:
public class SearchDialogAdapater implements ListAdapter, OnQueryTextListener,
OnItemClickListener, OnClickListener {
protected Stack<String[]> stackBeaches;
protected Stack<int[]> stackBeachesIds;
protected Activity context;
protected TreeMap<String, Integer> orderedBeaches;
protected ListView listView;
protected String lastFilter = "";
public SearchDialogAdapater(String[] bs, int[] bIds, Activity cont) {
this.stackBeaches = new Stack<String[]>();
this.stackBeachesIds = new Stack<int[]>();
this.stackBeaches.push(bs);
this.stackBeachesIds.push(bIds);
this.context = cont;
}
#Override
public boolean onQueryTextChange(String newText) {
filter(newText);
this.listView.setAdapter(this);
return true;
}
public void filter(String search) {
// no longer valid the previous selected, must clean selections
selectedPosition = -1;
lastView = null;
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
// hitted "backspace"
if (search.length() < lastFilter.length()) {
if (stackBeaches.size() > 1) {
stackBeaches.pop();
stackBeachesIds.pop();
}
lastFilter = search;
return;
}
// filter
ArrayList<String> filtBs = new ArrayList<String>();
ArrayList<Integer> filtBsIds = new ArrayList<Integer>();
for (int i = 0; i < stackBeaches.peek().length; i++) {
String beach = new String(stackBeaches.peek()[i]);
if (Pattern
.compile(Pattern.quote(search), Pattern.CASE_INSENSITIVE)
.matcher(beach).find()) {
filtBs.add(beach);
filtBsIds.add(stackBeachesIds.peek()[i]);
}
}
String[] beaches = new String[filtBs.size()];
int[] ids = new int[filtBsIds.size()];
int size = filtBs.size();
for (int i = 0; i < size; i++) {
ids[i] = filtBsIds.remove(0);// head
beaches[i] = filtBs.remove(0);
}
stackBeachesIds.push(ids);
stackBeaches.push(beaches);
lastFilter = search;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
String beach = stackBeaches.peek()[position];
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.dialog_item, null);
TextView txtBeach = (TextView) convertView
.findViewById(R.id.dialBeach);
txtBeach.setText(beach);
}
if (position == selectedPosition)// the same color below
convertView.setBackgroundColor(Color.argb(128, 0, 64, 192));
return convertView;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return stackBeachesIds.peek()[position];
}
#Override
public int getCount() {
return stackBeaches.peek().length;
}
#Override
public boolean isEmpty() {
return stackBeaches.peek().length == 0;
}
private View lastView;
private int selectedPosition = -1;
#Override
public void onItemClick(AdapterView<?> adapterView, View view,
int position, long arg3) {
// some color...
view.setBackgroundColor(Color.argb(128, 133, 181, 255));
selectedPosition = position;
if (lastView != null)
lastView.setBackground(null);
lastView = view;
((SurfApplication) context.getApplication()).setBeachId(stackBeachesIds
.peek()[position]);
if (!dialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled())
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(true);
}
protected AlertDialog dialog;
public void setDialog(AlertDialog dial) {
this.dialog = dial;
this.listView = dialog.getListView();
}
#Override
public void onClick(DialogInterface dialog, int which) {
((ProgressBar) context.findViewById(R.id.pBar))
.setVisibility(ProgressBar.VISIBLE);
int beachId = stackBeachesIds.peek()[selectedPosition];
String beach = stackBeaches.peek()[selectedPosition];
// do something... Here I am creating a new Intent and starting
// the new activity within my context
}
}
Same methods are not here because they return null or do nothing at all.
Sorry for long post, but I need to answer this properly.
Thank you all and I hope someone find this useful.
Your adapter needs to implement Filterable or extend from an adapter class that does. Adapters that already implement this interface, like ArrayAdapter, should do the filtering automatically for you.
Just call Adapter.getFilter().filter(...); with the value from the search view.
Related
I'm trying to create an alert dialog where the user can select multiple options from a pre-defined list, but if the option(s) they want to select aren't there, they can add them (via an edittext and "add" button).
So far, I've added the edittext and button to the top of the dialog using setCustomTitle, and I'm able to add the item to my source data list, but I can't figure out how to reapply this to the list in the dialog.
(Filter model just has a string and a boolean to determine whether it's selected, so if the user reopens the dialog I can set the selected items)
Here's my code so far...
private void selectSomething() {
AlertDialog.Builder selectSomethingBuilder = new AlertDialog.Builder(mContext);
View header = getLayoutInflater().inflate(R.layout.common_multichoice_dialog_header, null);
Button addButton = header.findViewById(R.id.btAdd);
EditText et = header.findViewById(R.id.textView2);
selectSomethingBuilder.setCustomTitle(header);
addButton.setOnClickListener(v -> {
cuisineList.add(new filterModel(et.getText().toString(), true));
boolean[] selectedItems2 = new boolean[cuisineList.size()];
for (int i = 0; i < cuisineList.size(); i++) {
selectedItems2[i] = cuisineList.get(i).isSelected();
}
String[] updatedList = cuisineList.stream().map(filterModel::toString).toArray(String[]::new);
//What to do here? How do I update the list of items with the newly added item
et.setText("");
});
boolean[] selectedItems = new boolean[cuisineList.size()];
for (int i = 0; i < cuisineList.size(); i++) {
selectedItems[i] = cuisineList.get(i).isSelected();
}
selectSomethingBuilder.setMultiChoiceItems(cuisineList.stream().map(filterModel::toString).toArray(String[]::new), selectedItems,
(dialog, which, isChecked) -> cuisineList.get(which).setSelected(isChecked));
selectSomethingBuilder.setPositiveButton(R.string.ok, (dialog, id1) -> {
setCuisineChips();
});
AlertDialog selectItems = selectSomethingBuilder.create();
selectItems.show();
}
Ok, so I got there by extending AlertDialog.Builder - for anyone who comes across this, here's the class I'm using:
public class multichoiceUserAddableDialog extends AlertDialog.Builder {
private final Context context;
private final MultiAdapter adapter;
public multichoiceUserAddableDialog(Context context, List<filterModel> selectList) {
super(context);
this.context = context;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View header = inflater.inflate(R.layout.common_multichoice_dialog_header, null);
Button addButton = header.findViewById(R.id.btAdd);
EditText et = header.findViewById(R.id.textView2);
this.setCustomTitle(header);
adapter = new MultiAdapter(context, android.R.layout.simple_list_item_multiple_choice, selectList);
addButton.setOnClickListener(v -> {
selectList.add(new filterModel(et.getText().toString(), et.getText().toString(), true));
et.setText("");
adapter.notifyDataSetChanged();
});
setAdapter(adapter, (dialogInterface, i) -> {
});
}
#Override
public AlertDialog create() {
AlertDialog x = super.create();
x.getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
((filterModel) adapterView.getItemAtPosition(i)).setSelected(!((filterModel) adapterView.getItemAtPosition(i)).isSelected());
adapter.notifyDataSetChanged();
}
});
return x;
}
private class MultiAdapter extends ArrayAdapter<filterModel> {
private List<filterModel> selectList;
ViewHolder holder;
public MultiAdapter(#NonNull Context context, int resource, #NonNull List<filterModel> selectList) {
super(context, resource, selectList);
this.selectList = selectList;
}
class ViewHolder {
CheckedTextView itemTV;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(
android.R.layout.simple_list_item_multiple_choice, null);
holder = new ViewHolder();
holder.itemTV = convertView.findViewById(android.R.id.text1);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.itemTV.setText(selectList.get(position).getText());
holder.itemTV.setChecked(selectList.get(position).isSelected());
return convertView;
}
}
}
This is then used like this:
multichoiceUserAddableDialog selectSomethingBuilder = new multichoiceUserAddableDialog(mContext, activityList);
selectSomethingBuilder.setPositiveButton(R.string.ok, (dialog, id1) -> {
setActivityChips();
});
AlertDialog selectItems = selectSomethingBuilder.create();
selectItems.show();
filterModel has a text field and a boolean (and any other fields you want), and the header layout has an editText and a button (plus a textview with some static text).
I want to display the item from a Listview by it's position. For Example: If i clicked on 3rd position i need to display the 3rd item. Here is my code. I want to display when the Item button is clicked.
for (int k = 0; k < jsonarrays.length(); k++) {
JSONObject main_menus = jsonarrays.getJSONObject(k);
SUB_MENU_ID = main_menus.getString(TAG_SUB_MENU_ID);
SUB_MENU_NAME = main_menus.getString(TAG_SUB_MENU_NAME);
HashMap<String, String> submenu = new HashMap<String, String>();
submenu.put(TAG_SUB_MENU_ID, SUB_MENU_ID);
submenu.put(TAG_SUB_MENU_NAME, SUB_MENU_NAME);
submenus.add(submenu);
}
#Override
protected void onPostExecute(String result) {
submenuadapter = new SubmenufoodCategoryAdapter(submenus, getActivity());
sb_list.setAdapter(submenuadapter);
sb_list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
});}
And this is My Adapter Class.:
public class SubmenufoodCategoryAdapter extends BaseAdapter {
ArrayList<HashMap<String, String>> mainmenu;
HashMap<String, String> mainmenumap = new HashMap<String, String>();
Context con;
public SubmenufoodCategoryAdapter( ArrayList<HashMap<String, String>> submenu, Context con) {
super();
this.mainmenu = submenu;
this.con = con;
}
#Override
public int getCount() {
return mainmenu.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#SuppressLint("ViewHolder")
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final Holder holder = new Holder();
LayoutInflater layoutInflater = (LayoutInflater) con.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mainmenumap = mainmenu.get(position);
View rowview;
rowview = layoutInflater.inflate(R.layout.submenu_button, null);
holder.btn = (Button) rowview.findViewById(R.id.submenu_layout_button);
holder.btn.setText(mainmenumap.get(FoodMenuItemFragment.TAG_SUB_MENU_NAME));
return rowview;
}
public class Holder {
Button btn;
}
}
Don’t compare this code with your requirement.. I am just giving you Idea..
I think You are trying to inflating all data from adapter to List-view .. I made a sample where I am displaying all details from adapter to List-view inside a Dialog so
builder.setAdapter(notes_second_adapter,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int position) {
notes_child_category_second.setText(notes_second_list
.get(position).get(KIDZDAY_TAG_DESCRIPTION));
acti_id_to_save = notes_second_list.get(position).get(
KIDZDAY_TAG_REF_ID);
//sampel_1 = "Nihal Srivastava";
}
});
dialog = builder.create();
dialog.show();
Here You can see. after getting data into adapter you can call ArrayList.get(position).value of that field.. By your click it will fetch data according to position
you can start another Activity and send these data with the Intent
You can give try to the following code snippet:
sb_list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//save data form here to some variables and on button click send data to where you want to show whether in new activity or something else
sbmenus.get(2).get(FoodMenuItemFragment.TAG_SUB_MENU_NAME);
}
});}
You can use a AlertDialog. Here is an example, answer 2.
public void dialogBox(String message) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setMessage(message);
alertDialogBuilder.setPositiveButton("Ok",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface arg0, int arg1) {
}
});
alertDialogBuilder.setNegativeButton("cancel",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface arg0, int arg1) {
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
Call the dialogBox(String) method on your itemClick(), with the data you want to display.
I have set my AlertDialog to CHOICE_MODE_MULTIPLE and get the data for the list from an API. It works almost fine, however, there are 2 problems I am having troubles with now.
The first one is more serious: After I check the items then click OK, sometimes when I go back to the dialog again it unchecks all of my checked items. This happens only 10-20% the times when I test so I do not know why it happens. I tried to save the values into a global variable in my class, or a public static variable I created when the app first started, still no luck.
When I click "Cancel", the checked items still update (it's supposed not to do so).
I am having a hard time against these 2 issues, any help is very much appreciated.
EDIT: Here is my custom dialog:
public class CustomMultichoiceDialog {
Set<String> selectedString = new HashSet<String>();
private String[] items;
private AlertDialog dialog;
private Builder builder;
private Context context;
private TestAdapter adapter;
public CustomMultichoiceDialog(Context context, String[] items) {
this.context = context;
this.items = items;
builder = new AlertDialog.Builder(context);
this.adapter = new TestAdapter(context, android.R.layout.simple_list_item_checked, this.items);
builder.setAdapter(this.adapter, null);
}
public AlertDialog show() {
if (this.dialog == null) {
this.create();
}
this.adapter.notifyDataSetChanged();
this.dialog.show();
return this.dialog;
}
public String[] getSelectedItems() {
String[] result = new String[this.dialog.getListView().getCheckedItemCount()];
SparseBooleanArray checked = this.dialog.getListView().getCheckedItemPositions();
int k = 0;
for (int i = 0; i < this.items.length; i++) {
if (checked.get(i)) {
result[k++] = this.items[i];
}
}
return result;
}
public String getSelectedItemAsString() {
return Arrays.toString(this.getSelectedItems()).replace("[", "").replace("]", "")
.replace(", ", ",");
}
public AlertDialog create() {
this.dialog = builder.create();
this.dialog.getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
this.dialog.getListView().setSelector(new ColorDrawable(Color.TRANSPARENT));
return this.dialog;
}
public void setPositiveButton(final Callbacks callbacks) {
this.builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
String[] selected = getSelectedItems();
callbacks.run(selected, getSelectedItemAsString());
cacheSelectedItems(selected);
}
});
}
public void setNegativeButton(final Callbacks callbacks) {
this.builder.setNegativeButton(this.context.getString(R.string.cancel),
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
});
}
private void cacheSelectedItems(String[] selected) {
selectedString.addAll(Arrays.asList(selected));
}
public interface Callbacks {
public void run(String[] selectedItems, String selectedItemAsString);
}
class TestAdapter extends ArrayAdapter<String> {
public TestAdapter(Context context, int resource, String[] objects) {
super(context, resource, objects);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
ViewHolder holder = (ViewHolder) view.getTag();
if (holder == null) {
holder = new ViewHolder();
holder.text = ((CheckedTextView) view.findViewById(android.R.id.text1));
holder.text.setCheckMarkDrawable(R.drawable.checkbox);
}
if(selectedString!=null){
if(selectedString.contains(holder.text.getText().toString())) {
holder.text.setSelected(true);
holder.text.setChecked(true);
}
}
return view;
}
class ViewHolder {
CheckedTextView text;
}
#Override
public long getItemId(int position) {
return position;
}
}
}
I have an AlertDialog which it has dynamic items linked to a Cursor from database , it works fine but i wanted to disable user interaction with that because it's an informational dialog , i've disabled my dialog with :
alert.getListView().setEnabled(false);
but the problem is when Items in the list are bigger than the dialog height , because of disabling it's ListView, Scrolling is disabled too and some items doesn't show up, i've tried some links like : Android : How to disable CheckBox in AlertDialog?
with no success. i've also tried :
builder.setMultiChoiceItems(mDBAdapter.instance.getName(SupervisorGuid)
, SyncDBHelper.instance.SentSupervisors(SupervisorGuid),new DialogInterface.OnMultiChoiceClickListener() {
#Override
public void onClick(DialogInterface dialog, int which,
boolean isChecked) {
if(isChecked==true)
{
((AlertDialog) dialog).getListView().setItemChecked(which, false);
}
else
{
((AlertDialog) dialog).getListView().setItemChecked(which, true);
}
}});
AlertDialog alert = builder.create();
Does anybody know a better way to disable the checkboxes without a Custom dialog?
Thanks in Advance.
this may give you some idea...
private void showDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
ArrayList<String> arrayList = new ArrayList<String>();
ArrayList<Boolean> selectedList = new ArrayList<Boolean>();
for (int i = 1; i <= 20; i++) {
arrayList.add("" + i);
selectedList.add(i % 2 == 0);
}
builder.setAdapter(new MyAdapter(arrayList, selectedList), null);
builder.show();
}
public static class MyAdapter extends BaseAdapter {
private ArrayList<String> arrayList;
private ArrayList<Boolean> selectedList;
public MyAdapter(ArrayList<String> arrayList,
ArrayList<Boolean> selectedList) {
this.arrayList = arrayList;
this.selectedList = selectedList;
}
#Override
public int getCount() {
return arrayList.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
return getView(parent.getContext(), position);
}
private RelativeLayout getView(Context context, int position) {
RelativeLayout relativeLayout = new RelativeLayout(context);
AbsListView.LayoutParams params = new AbsListView.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
relativeLayout.setLayoutParams(params);
TextView textView = new TextView(context);
textView.setText(arrayList.get(position));
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
layoutParams.addRule(RelativeLayout.CENTER_VERTICAL);
layoutParams.leftMargin = 30;
textView.setLayoutParams(layoutParams);
relativeLayout.addView(textView);
CheckBox checkBox = new CheckBox(context);
layoutParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
layoutParams.rightMargin = 30;
checkBox.setLayoutParams(layoutParams);
checkBox.setClickable(false);
if (selectedList != null) {
checkBox.setChecked(selectedList.get(position));
}
relativeLayout.addView(checkBox);
return relativeLayout;
}
}
I had the same problem and solved it this way:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
...
builder
.setTitle(...)
.setMultiChoiceItems(cursor, IS_CHECKED, LABEL, new DialogInterface.OnMultiChoiceClickListener() {
#Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
((AlertDialog)dialog).getListView().setItemChecked(which, /* assign here the original boolean value of the item */);
}
})
...
AlertDialog dialog = builder.create();
dialog.show();
In summary, when you click the item in the list, just set its value back to the original boolean value.
you can define your check box value with boolean array
"checkValues" is our boolean array which defines which check box should tick or which not. check below ex.
builder.setMultiChoiceItems(dialogList, checkedValues)
private fun showDialog() {
val dialogList: Array<String> = days
val checkedValues = BooleanArray(days.size)
checkedValues[viewpager.currentItem] = true
val builder: AlertDialog.Builder = AlertDialog.Builder(activity)
builder.setTitle("You can copy"+dialogList[viewpager.currentItem]+" time slot to:")
builder.setMultiChoiceItems(dialogList, checkedValues)
{ dialog, which, isChecked ->
(dialog as AlertDialog).listView.setItemChecked(yourIndex, true)
}.setPositiveButton("OK") { dialog, id ->
dialog.dismiss()
}.setNegativeButton("Cancel") { dialog, id ->
dialog.dismiss()
}.show()
}
I have a list view with multi columns... Want to change the background color of a row item that is selected or clicked. Have referred to various articles on stackoverflow but they dont seem to help...What i ve done in OnItemClick is .setBackgroundColor. Cannot use the selector as would want to remember the color change in the sense the row that I have changed color for, when the application relaunches should remember the change...I put the flag value in database and can set the color in getView but how to do it for first time? Here is the code.....
public class AdminMultiColumn extends Activity
{
private ArrayList<HashMap<String,String>> list;
ArrayList<String> al;
AlertDialog.Builder alertDialogBuilder;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.admin_checkoutlist);
lview = (ListView)findViewById(R.id.admin_list);
populateList();
Admin_checkoutlist adapter = new Admin_checkoutlist(this,list);
lview.setAdapter(adapter);
}
private void populateList() {
list = new ArrayList<HashMap<String,String>>();
al = new ArrayList<String>();
testday = c.get(Calendar.DAY_OF_MONTH);
testmonth = c.get(Calendar.MONTH)+1;
testyear = c.get(Calendar.YEAR);
dateget = testday+"-"+testmonth+"-"+testyear;
mdb.open();
va.open();
Cursor c1 = va.getNameTimeinTimeout(dateget);
DatabaseUtils.dumpCursor(c1);
if(c1.moveToFirst())
{
do{
idfromdb = c1.getString(0);
al.add(idfromdb);
namefromdb = c1.getString(1);
al.add(namefromdb);
timefromdb = c1.getString(2);
al.add(timefromdb);
timeoutfromdb = c1.getString(3);
al.add(timeoutfromdb);
}while(c1.moveToNext());
}
c1.close();
va.close();
mdb.close();
Log.d("pavan","data retrived "+namefromdb+" "+timeoutfromdb+" "+timefromdb+" "+idfromdb);
for(int i = 0;i<al.size();i=i+4)
{
temp = new HashMap<String,String>();
temp.put(FIRST_COLUMN, al.get(i));
temp.put(SECOND_COLUMN, al.get(i+1));
temp.put(THIRD_COLUMN, al.get(i+2));
temp.put(FOURTH_COLUMN, al.get(i+3));
Log.d("pavan","test here for admin");
list.add(temp);
}
}
//adapter class goes here////////////
public class Admin_checkoutlist extends BaseAdapter implements OnItemClickListener
{
public ArrayList<HashMap<String,String>> list;
Activity activity;
public Admin_checkoutlist(Activity activity, ArrayList<HashMap<String,String>> list)
{
super();
this.activity = activity;
this.list = list;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
#Override
public Object getItem(int pos) {
// TODO Auto-generated method stub
return list.get(pos);
}
#Override
public long getItemId(int pos) {
// TODO Auto-generated method stub
return 0;
}
public class ViewHolder
{
TextView txtFirst;
TextView txtSecond;
TextView txtThird;
TextView txtFOURTH;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
LayoutInflater inflater = activity.getLayoutInflater();
if (convertView == null)
{
convertView = inflater.inflate(R.layout.temp, null);
holder = new ViewHolder();
holder.txtFirst = (TextView)convertView.findViewById(R.id.uid);
holder.txtSecond = (TextView)convertView.findViewById(R.id.nametext);
holder.txtThird = (TextView)convertView.findViewById(R.id.checkintext);
holder.txtFOURTH = (TextView)convertView.findViewById(R.id.checkouttext);
convertView.setTag(holder);
lview.setOnItemClickListener(this);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
HashMap<String, String> map = list.get(position);
holder.txtFirst.setText(map.get(FIRST_COLUMN));
holder.txtSecond.setText(map.get(SECOND_COLUMN));
holder.txtThird.setText(map.get(THIRD_COLUMN));
holder.txtFOURTH.setText(map.get(FOURTH_COLUMN));
return convertView;
}//getview ends here.
#Override
public void onItemClick(final AdapterView<?> parent, final View view, int pos,
long id) {
// TODO Auto-generated method stub
Object listItem = parent.getFirstVisiblePosition()+pos+1;
//lview.getChildAt(pos).setBackgroundColor(R.color.blue);
view.setBackgroundColor(pos);
idtosend = listItem.toString();
Log.d("pavan","id is"+idtosend);
/////alert displaing block starts here////////////////////////////////
alertDialogBuilder = new AlertDialog.Builder(AdminMultiColumn.this);
alertDialogBuilder.setTitle("Alert");
alertDialogBuilder
.setMessage("Check out now")
.setCancelable(false)
.setPositiveButton("Yes",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
// if this button is clicked, close
// current activity
Toast.makeText(getApplicationContext(), "Checkout successfull", Toast.LENGTH_LONG).show();
testhour = c.get(Calendar.HOUR_OF_DAY);
testmin = c.get(Calendar.MINUTE);
testsec = c.get(Calendar.SECOND);
timings = testhour+":"+testmin+":"+testsec;
mdb.open();
va.open();
va.upDate(idtosend,timings);
Toast.makeText(getApplicationContext(), "update the checkout options "+timings, Toast.LENGTH_SHORT).show();
va.close();
mdb.close();
/*Intent go = new Intent(AdminMultiColumn.this,MultiColumn.class);
startActivity(go);*/
}
})
.setNegativeButton("No",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
// if this button is clicked, just close
// the dialog box and do nothing
dialog.cancel();
}
});
// create alert dialog
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
///////alert displaing block ends here//////////////////////////////////
}
}
}
What I have done now is within the getView method, taking the convertView and setting the background resource to a color, that too is not working...below is the code...
if(holder.txtFOURTH!=null)
{
convertView.setBackgroundColor(R.drawable.image_border);
}
else
{
Toast.makeText(getApplicationContext(), "test", Toast.LENGTH_SHORT).show();
}
There two points -
pos is not a good option as color
Instead of view.setBackgroundColor(pos); sue
LinearLayout row = (LinearLayout)view.findViewById(R.id.list_row);
if(null!=row){
//<listAdapter>.notifyDataSetChanged();
row.setBackgroundResource(R.drawable.);
}
assuming the your list row has LinearLayout in root having id "list_row", chage this as per your layout.
but there will be problem this as when you click on the second row it also be selected stated and better to call list.notifydatasetchaged there are few more option look over them, may fill your requirement
android-selected-state-listview-example
android-how-do-i-highlight-a-row-in-listview
highlighting-the-selected-item-in-the-listview-in-android