Radio Button layout not appearing with listview/adapter in dialog - android

I'm fairly new to Android but am trying my hardest to get a handle on it. I've been researching this most of the day and I've concluded that there must be an issue with my actual adapter.
Unfortunately when I load up my dialog box I don't get the list view populating.
My Goal
I want to have a dialog that appears that is a custom layout that contains a listview. This has been created and has been demonstrated to work with other adapters. When the listview appears I want one option selected automatically with the radio buttons.
Custom Dialog XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#drawable/dialog_main_style">
<TextView
android:id="#+id/main_title_dialog"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingBottom="12dp"
android:paddingTop="12dp"
android:text="Format"
android:textColor="#020202"
android:textSize="20sp" />
<View
android:id="#+id/dialog_top_divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_below="#+id/main_title_dialog"
android:layout_marginBottom="12dp"
android:background="#e4e4e4" />
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/format_choices_list_view"/>
<TextView
android:id="#+id/ok_change_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/dialog_gradient_button"
android:gravity="center"
android:layout_below="#id/dialog_top_divider"
android:padding="16dp"
android:text="OK"
android:textColor="#009261"
android:textStyle="bold" />
</LinearLayout>
Nothing special here, just a reference to my custom layout and my ListView.
Custom Listview for radio buttons
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<RadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/format_radio_button"
android:text="mp3"
android:button="#null"
android:drawableRight="#android:drawable/btn_radio"
android:layout_marginRight="16dp"
android:layout_marginEnd="16dp"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp" />
</LinearLayout>
Normally radio buttons need a radio group but as it's a custom layout I want to use it seems like I'd only need 1 radio button?
Creating the Dialog and adapter
private void showFormatChangeDialog() {
//TODO get the list view working in the dialog
Dialog changeFormatDialog = new Dialog(SettingsActivity.this);
changeFormatDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
changeFormatDialog.setContentView(R.layout.change_audio_format_dialog);
changeFormatDialog.getWindow().getAttributes().width = WindowManager.LayoutParams.MATCH_PARENT;
ListView formatListView = (ListView) changeFormatDialog.findViewById(R.id.format_choices_list_view);
AudioFormatAdapter adapter = new AudioFormatAdapter(SettingsActivity.this);
formatListView.setAdapter(adapter);
changeFormatDialog.show();
}
I create a dialog and set it to my custom dialog layout. I then get a reference to my list view and crate an adapter and set it.
FormatAdapter
public class AudioFormatAdapter extends ArrayAdapter<String> {
static class ViewHolder {
RadioButton radioButton;
}
private String formatNames[] = {"mp3", "wav","amr"};
public AudioFormatAdapter(Context c) {
super(c, 0);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View formatView = convertView;
ViewHolder holder;
if(formatView == null) {
formatView = LayoutInflater.from(getContext()).inflate(R.layout.list_view_formats_layout, parent, false);
holder = new ViewHolder();
holder.radioButton = (RadioButton) formatView.findViewById(R.id.format_radio_button);
holder.radioButton.setText(formatNames[position]);
formatView.setTag(holder);
} else {
holder = (ViewHolder)formatView.getTag();
}
return formatView;
}
}
My goal here is to get a reference to my custom list view for the radio button. I grab a reference of the radio button and set the text to my array value based on the position.
I don't seem to get any data back from this ArrayAdapter and it's been blowing my mind. I've used several ArrayAdapter since I started and I haven't had this trouble. When I replaced this adapter with a different one it worked. I'm not sure what the issue is here.
Any help would be greatly appreciated.
Thank you.

Well it's fixed what I wanted and I think it came down to the adapter failing. Now I'm aware my adapter does not have a ViewHolder but it has a limit amount of options so it's ok for now.
First I needed a class that allowed a CheckableLinearLayout. This is a special type of LinearLayout that allows sections of the layout to be checked and unchecked. You simply make a new class of it and then add it to your XML file as the rootview. com.YOUR-IDENTIFIER-CLASS-NAME-OF-CHECKABLELINEARLAYOUT :) You can see it in the link below!
Checkable Linear Layout - Found here - How do a custom listview item with a radiobutton and single choice
After using that class I made a different adapter that was much simplier and it just seemed to work.
Adapter
public class AudioFormatAdapter extends ArrayAdapter<String> {
private ArrayList<String> formats;
public AudioFormatAdapter(Context c){
super(c, 0);
}
public AudioFormatAdapter(Context c, ArrayList<String> choices){
super(c, 0, choices);
formats = choices;
}
#Override
public View getView(final int position, final View convertView, ViewGroup parent) {
View listItemView = convertView;
listItemView = LayoutInflater.from(getContext()).inflate(R.layout.list_view_formats_layout, parent, false);
CheckedTextView _radioButton = (CheckedTextView) listItemView.findViewById(R.id.format_radio_button);
_radioButton.setText(formats.get(position));
return listItemView;
}
}
As we can see this adapter gets a "CheckedTextView" instead of the radio button. The reason for this is that I simply needed a radio button style with some text and this gives me that.
I set the text with an arrayList that I pass to the adapter in "formats"
Finally I create the Dialog and get a reference to my list view.
Dialog Creation with custom layout
private void showFormatChangeDialog(ArrayList<String> formatNames) {
LayoutInflater inflater = LayoutInflater.from(SettingsActivity.this);
View dialogLayout = inflater.inflate(R.layout.change_audio_format_dialog, null);
AlertDialog.Builder builder = new AlertDialog.Builder(SettingsActivity.this);
builder.setView(dialogLayout);
final ListView formatListView = (ListView) dialogLayout.findViewById(R.id.format_choices_list_view);
formatListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
final AudioFormatAdapter adapter = new AudioFormatAdapter(SettingsActivity.this, formatNames);
formatListView.setAdapter(adapter);
AlertDialog customDialog = builder.create();
customDialog.show();
}
If you only want one of the options selected then set the mode to SINGLE_CHOICE. I make the adapter here and pass in a list of strings which are accepted as a parameter to my function. Then the dialog is created
Conclusion
This was a rather irritating process as I think my adapter was breaking most things, I hope my trolling around the Internet and finding out bits and pieces can help someone else. Now I just need to save and store data depending on which option is selected!
I hope this helps somebody!

Related

ListView - differentiate between a checkbox selection and a text selection

Given the ListView below, I wanted to perform two different actions depending on whether the user selects the text (create a new activity) or clicks the associated checkbox (add it to a favorites list). Is this possible in with this setup or will I have to use a custom adapter or even a different layout?
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_multiple_choice, teams));
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String team_name = adapterView.getItemAtPosition(i).toString().trim();
Intent intent = new Intent("blah.blah.blah");
intent.putExtra("team", team_name);
startActivity(intent);
}
});
A
If I am understanding you correctly, your ListView should contain TextBox and CheckBox and TextBox and CheckBox are clickable, not ListView itself.
For this you have to make custom adapter, where you will make listeners for both the TextBox and CheckBox.
public class CustomAdapter extends BaseAdapter {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// your_costum_view should contain textbox and checkboc
view = inflater.inflate(R.layout.your_costum_view, null);
// Get your checkbox and textbox and add listeners
TextView textView = (TextView) view.findById(R.id.textView);
textView.setOnClickListener...
Checkbox checkbox=(CheckBox)view.findById(R.id.checkBox);
checkBox.setOnClickListener...
return view;
}
}
your_costum_view layout example
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<CheckBox
android:id="#+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
Using a custom adapter will help you keep trace of your views, it will be easier than use a default adapter that you can't control. For references: http://www.vogella.com/tutorials/AndroidListView/article.html#adapterown_custom
Using a custom adapter will definitely make your life easier. In the adapter you can make reference to both the checkbox and the textView and add an onClick Listener to each - from there you can also add code to handle each event. I would also suggest using a recyclerView instead of a ListView. It is the new thing in Android 5.0 and it really is easier to use then a regular ListView. Hope this helps:
RecyclerView Help
Set the CheckBox as focusable="false" in your XML layout.
android:focusable="false"
if don't run go to this link and see example because you need a create custom row in list view and set:
Checkbox checkbox=(CheckBox)view.findById(R.id.checkboxID);
checkbox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//do stuff
}
});

Two clickable item in same row of listview

How can I place 2 items in the same row in listview?
e.g
item 1 | item 2
item 3 | item 4
item 5 | item 6
and so on.
I don't have a problem with drawing them and there are a lot of various ways to draw them.
My problem: I cannot find a propper way to listen when I clicked on item 1 or item 2.
Also, I am considering to simply make 2 listview, populate them independently and rotate simultaneously, but I hope there is better way.
You should use a custom adapter for your listView. In the adapter you inflate your own layout for each row and listen for events for each view. This is an example of a custom Adapter: Custom Adapter for List View
Hope it helps you!!
for each item add this to listview row layout:
android:focusable="false"
and then in getView find each item and then assign it the appropriate click listener.
Use CustomAdapter for listview and add items in collection for example an ArrayList.
CustomAdapter adapter=new CustomAdapter(getApplicationContext(),R.id.listview_id,itemlist);
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
>
<TextView android:id="#+id/item1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dip"
android:textSize="16sp"
android:textStyle="bold"
android:textColor="#000000"
/>
<TextView android:id="#+id/item2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dip"
android:textSize="16sp"
android:textStyle="bold"
android:textColor="#000000"
/>
</LinearLayout>
CustomAdapter.java
public class CustomAdapter extends CustomAdapter<String>{
//Declare variables variables here..
public CustomAdapter(Context context, int resource,
List<String> objects) {
//initialize and set constructor values here..
}
public static class ViewHolder {
TextView textitem1;
TextView textitem2
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View row = convertView;
ViewHolder holder = null;
if(null == row) {
LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.list_item, parent, false);
holder = new ViewHolder();
holder.textitem1 = (TextView) row.findViewById(R.id.item1);
holder.textitem2 = (TextView) row.findViewById(R.id.item2);
row.setTag(holder);
}
return view;
}
}
You can add as many TextViews you want. Depending on requirement, you can alter their position/height/width etc.
For listening Click event,
For each text view add android:clickable="true"
Use a CustomAdapter and set ClickListeners for each TextView in getView method.
Hope This Helps!
And i found way wich is suitable for me for 100%
Idea is to use GridView~ instead ofListView`.
<GridView
android:id="#+id/gridview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:numColumns="2"
android:stretchMode="columnWidth" />
In fact I dont even need to change and single line in my original adapter. android:numColums set how much colums you want to display. You can place int there or auoto_fit.

(Android) How do i access and modify a specific element in a custom listview, seeing as it uses a custom adapter?

I have a custom list view, here is its layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:id="#+id/playerToken"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/playerName"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/playerMoney"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
And here is the custom Adapter which takes an array of a Player Object which stores information like the players name, his token to represent him, and his money balance. the adapter takes that information and populates my custom list, as the layout above.
public class MyAdapter extends ArrayAdapter<Player> {
public MyAdapter(Context context, Player[] values) {
super(context, R.layout.activity_banking_layout, values);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater theInflater = LayoutInflater.from(getContext());
View theView = theInflater.inflate(R.layout.activity_banking_layout, parent, false);
Player player = getItem(position);
TextView playerNameText = (TextView) theView.findViewById(R.id.playerName);
TextView playerMoneyText = (TextView) theView.findViewById(R.id.playerMoney);
ImageView playerToken = (ImageView) theView.findViewById(R.id.playerToken);
playerNameText.setText(player.getName());
playerMoneyText.setText(Integer.toString(player.getMoney()));
int rId = theView.getResources().getIdentifier(player.getToken(), "drawable",
getContext().getPackageName());
playerToken.setImageResource(rId);
return theView;
}
}
This is just the layout showing the listView that us being adapted:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:padding="10dp"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/bankListView" />
</LinearLayout>
So basically, my list is created and adapter in the onCreate method of the activity showing the list. After that my list items can open a context menu and depending on what is selected the player objects are manipulated. I want my list to reflect these changes, so i was wondering how i can access a specific part of my custom list and edit it. For example my custom list has a player icon, and to the right, the players name and below the name a money amount. Lets say i want to change the money amount of a specific player and reflect that change on the list, how do i access that specific TextView, within that specific position in that ListView ?
Since your adapter 'MyAdapter' extends ArrayAdapter, you can try using getItem(int position) which return the list item at the specified position; a Player object in your case. From there, you can modify your object's data member (amount of money) and then refresh the list to reflect your changes with notifyDataSetChanged().
In case you wanted to know the index/position of the clicked list item, then your question would be a duplicate of this one.
instead of manipulating the textview, consider the following approach:
make the Player[] array a global variable, instead of passing it to constructor,. then manipulate the Player object directly, then call
notifyDataSetChanged()
on your adapter which will automatically update your correct textview.
private Player[] values;
public void onCreate(Bundle s){
/*your onCreate things*/
MyAdapter adapter = new MyAdapter(this);
// update player 5 from array
values[4].money = newMoneyVal;
// after updating, call notifyDataSetChanged()
adapter.notifyDataSetChanged();
}
public class MyAdapter extends ArrayAdapter<Player> {
public MyAdapter(Context context) {
super(context, R.layout.activity_banking_layout, values);
}
/*rest of your adapter class*/
}
let me know if this works or if you have any questions
Yuo just have to implement a onlistitemclick listener, like this:
#Override
protected void onListItemClick(ListView l, View v, int pos, long id) {
super.onListItemClick(l, v, pos, id);
l[pos].findViewById(R.id.yourTagName).setText("ChangedValue");//to be adapted
}

Why does ListView stays above TextView in ListPreference dialog?

I need to create a custom ListPreference dialog so that I can add some header text (a TextView) above the List (ListView).
I've created MyListPreference class that extends ListPreference and overrides onCreateDialogView():
#Override
protected View onCreateDialogView() {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = (View) inflater.inflate(R.layout.dialog_preference_list, null);
return v;
}
My XML layout dialog_preference_list.xml contains:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
<ListView
android:id="#android:id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawSelectorOnTop="false"
android:scrollbarAlwaysDrawVerticalTrack="true" />
</LinearLayout>
Problem: The TextView is displayed below the ListView instead of above. I need the TextView to be above. I've tried both with LinearLayout and RelativeLayout (using "below" or "above" attributes) with no success: I can't find a way to put the TextView above the ListView... The layout is pretty simple and I cannot see why the list stays above...
Also, note that the problem occurs on both a real device (Nexus 4, Android 4.2.2) and the emulator. However, when looking at the layout rendered in Eclipse's graphical layout, the layout is correct! See both attached pictures.
Any idea on how to solve this?
Layout rendered on the device (incorrect):
Layout rendered on Eclipse (correct):
Edit with solution 10.07.2013
As suggested by the accepted answer, the problem comes from the use of builder.setSingleChoiceItems() in ListPreference's onPrepareDialogBuilder().
I've fixed it by extending ListPreference and overriding onCreateDialogView() to build the Dialog without the builder so that I can create a custom View showing the header text above the list items.
GPListPreference.java:
public class GPListPreference extends ListPreference {
...
#Override
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
builder.setNegativeButton(null, null);
builder.setPositiveButton(null, null);
}
private int getValueIndex() {
return findIndexOfValue(getValue());
}
#Override
protected View onCreateDialogView() {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ListView lv = (ListView) inflater.inflate(R.layout.dialog_preference_list, null);
TextView header = (TextView) inflater.inflate(R.layout.dialog_preference_list_header, null);
header.setText(getDialogMessage()); // you should set the header text as android:dialogMessage in the preference XML
lv.addHeaderView(header);
ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(getContext(), R.layout.dialog_preference_list_singlechoice, getEntries());
lv.setAdapter(adapter);
lv.setClickable(true);
lv.setEnabled(true);
lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
lv.setItemChecked(getValueIndex() + 1, true);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
setValueIndex(position - 1);
getDialog().dismiss();
}
});
return lv;
}
}
dialog_preference_list.xml:
<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawSelectorOnTop="false"
android:scrollbarAlwaysDrawVerticalTrack="true" />
dialog_preference_list_singlechoice.xml
<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:checkMark="?android:attr/listChoiceIndicatorSingle"
android:ellipsize="marquee"
android:gravity="center_vertical"
android:minHeight="?android:attr/listPreferredItemHeight"
android:paddingBottom="2dip"
android:paddingLeft="10dip"
android:paddingRight="10dip"
android:paddingTop="2dip"
android:textAppearance="?android:attr/textAppearanceMedium" />
dialog_preference_list_header.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dip"
android:textAppearance="?android:attr/textAppearanceSmall">
</TextView>
I think the problem is with the way ListPreference works. ListPreference uses Builder.setSingleChoiceItems() to create the rows with the RadioButtons, and it has preference over the custom layout you are trying to add (in your case a TextView and a ListView inside a LinearLayout. The solution is extending DialogPreference instead. Here is a link to a GitHub where I created a custom DialogPreference that does what you need. I haven't coded the RadioButton logic.
I guess it's a theming issue. Try changing the theme of your dialog inside the constructor make it something like setStyle(STYLE_NO_TITLE, R.style.AppTheme). Your base app theme with no_title style.
If this is not the issue than it might be related with the ListPreference class itself. It might be overriding your layout for consistency in theming the preference views. However, I have not used ListPreference before, so its just a guess.
Can you reproduce the same result by playing with the themes in XML graphical layout preview?
Another option you can try is to add the TextView as a header to the ListView like this:
TextView textView = new TextView(getActivity());
ListView listView = new ListView(getActivity());
listView.addHeaderView(textView);
The addHeaderView takes a View so you theoretically have anything you want to be the header, but I have only used a TextView.
The link above is broken. On this solution the idea is overriding the ListPreference, and inflating your own listview, with the data defined on the ListPreference.
#Override
protected View onCreateDialogView() {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ListView lv = new ListView(getContext());
// Inflate the view into the header only if a message was set
if (getDialogMessage() != null && ! getDialogMessage().equals("") ) {
TextView header = (TextView) inflater.inflate(R.layout.dialog_preference_list_header, null);
header.setText(getDialogMessage());
lv.addHeaderView(header, null, false);
}
// Create a new adapter and a list view and feed it with the ListPreference entries
ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(getContext(),
R.layout.custom_dialog_single_choice_list_adapter, getEntries());
lv.setAdapter(adapter);
lv.setClickable(true);
lv.setEnabled(true);
lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
lv.setItemChecked(getValueIndex() + 1, true);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
setValueIndex(position - 1);
getDialog().dismiss();
}
});
return lv;
}
Another important thing is to call onPrepareDialogBuilder and not calling super in it. This will avoid that the listview appears twice.
#Override
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
// Not calling super, to avoid having 2 listviews
// Set the positive button as null
builder.setPositiveButton(null, null);
}
private int getValueIndex() {
return findIndexOfValue(getValue());
}
Where dialog_preference_list_header is in my case only a TestView, but it could be a more complex view, and custom_dialog_single_choice_list_adapter could be something like this:
<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:checkMark="?android:attr/listChoiceIndicatorSingle"
android:ellipsize="marquee"
android:gravity="center_vertical"
android:minHeight="?android:attr/listPreferredItemHeight"
android:paddingBottom="2dip"
android:paddingLeft="10dip"
android:paddingRight="10dip"
android:paddingTop="2dip"
android:textAppearance="?android:attr/textAppearanceMedium" />

How to wrap text using simple_list_item_multiple_choice?

I'm using a SimpleCursorAdapter to display a single CheckedTextView. I know this is done best using simple_list_item_multiple_choice and android.R.id.text1.
adapter = new SimpleCursorAdapter(getApplicationContext(),
android.R.layout.simple_list_item_multiple_choice, rules,
new String[]{Constants.KEY_RULE}, new int[]{android.R.id.text1});
If the text from KEY_RULE is more than two lines, android doesn't wrap, instead it hides it. Is there an easy work-around for this without having to implement my own adapter?
Find my xml code below:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="#+id/header" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="#string/rule_selection_for_revision_list_title"
android:padding="4dip" android:background="#000000" android:textColor="#ffffff" android:textStyle="bold" />
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_weight="1.0" />
<TextView android:textSize="18sp" android:textStyle="bold"
android:id="#id/android:empty" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:gravity="center_vertical|center_horizontal"
android:text="There are no rules to consider." />
</LinearLayout>
Is there any way I can at least reduce the font size so that it fits to two lines?
There are several options.
You can define your custom layout for item in the list. This allows you to fully customize your item UI. More details can be found in List View tutorial.
The other approach can be used if you still want to use standard item layout but only fix one small thing in it. You can extend Adapter and modify the view in getView function. Here is an example:
class MySimpleCursorAdapter extends SimpleCursorAdapter
{
public MySimpleCursorAdapter(Context ctx, int layout,
Cursor cursor, String [] from, int [] to)
{
super(ctx, layout, cursor, from, to);
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
View view = super.getView(position, convertView, parent);
TextView textView = (TextView)view.findViewById(android.R.id.text1);
//You can increase number of lines in the text view
textView.setMaxLines(5);
LayoutParams params = textView.getLayoutParams();
if(params.height > 0)
{
int height = params.height;
params.height = LayoutParams.WRAP_CONTENT;
textView.setLayoutParams(params);
textView.setMinHeight(height);
}
//Or you can make your font smaller
textView.setTextSize(customTextSize);
//or whatever you like, even apply new custom style
//...
return view;
}
}
You should probably choose the first approach (custom layout), but sometimes the second approach is feasible too.
You don't need to implement a custom Adapter. Just define a custom layout for the list items and pass it to the adapter instead of android.R.layout.simple_list_item_multiple_choice.
You can search the Android sources (come with the SDK on you computer) to how the original simple_list_item_multiple_choice layout looks like and adapt it to your needs.

Categories

Resources