android - showing listView in PreferenceActivity - android

i wish to show a listView on a PreferenceActivity similar to what the android OS wifi-settings has for the list of networks (example here , on the bottom area of the image) .
however , such a thing isn't availabe , so i've created a new class that extends Preference , and what i returned in the onCreateView is just a ListView instance .
it worked , but the listView has a constant size of about a single item no matter what i do to its layoutParams and no matter what i do to the adapter . even if i set the adapter inside the onCreateView , it has the exact same size .
not only that , but the listView cannot be scrolled , even though it is clear that it has multiple items within it .
i would , of course, want to use the same text size standard as on all of the preferences , to give a native feeling.
can anyone please tell me what can be done in order to make it work well?
btw, the app should work for android API 10+ (minimum 10) .

In case you are going for the same appearance / behavior, you should stay with the plain PreferenceActivity implementation, and add the new preference items into the "list" dynamically from code (eventually with custom renderers).
A basic implementation of such display would be:
/**
* This variable stands for the items with which you want to populate the list
*/
final HashMap<String, String> networks = new HashMap<String, String>();
final PreferenceCategory cat = new PreferenceCategory(getApplicationContext());
cat.setTitle(R.string.wifinetworks); // holding "Wi-fi networks"
for (final String networkTitle : networks.keySet())
{
final Preference pref = new Preference(getApplicationContext());
pref.setTitle(networkTitle);
pref.setSummary(networks.get(networkTitle));
cat.addPreference(pref);
}
Edit: For adding custom components to an existing PreferenceActivity, you should give a try to the addContentView method. From within onCreate:
final LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT);
addContentView(buttonBar, params);

ok , the answer would be to use setContentView to whatever layout you wish (including any views you wish) , add there a listView for the preferences , and for this listView , call bind and setAdapter.
i've found this solution by looking at other solutions, like this one:
http://kmansoft.com/2011/08/29/implementing-long-clickable-preferences/

Related

Setting tags to each item in a ListView in Android?

I have a ListView where I want each item to have an ID number attached to it (not the same as the position number). I was hoping this could be done by setting a tag to each View item in the ListView using setTag() when these Views are being created.
Right now I'm creating the ListView like this:
final ListView listview = (ListView) findViewById(R.id.listView1);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1, names);
listview.setAdapter(adapter);
The names variable in the ArrayAdapter parameters above is an ArrayList, and each string value in this list also has a unique ID that I want to link to this string somehow.
Is there any way I can get access to and modify each of the Views with a tag? One idea was to create my own extended class of ArrayAdapter and override the getView() method, but I don't really understand how it works and how I would go about doing this.
Or is there a better way to link IDs with each string like this than adding tags like I'm trying to do?
Create a ViewBinder and set the tags as the ListView is being populated with whatever you need. You can check all properties of the view to determine what tag goes where, so this should be what you're looking for.
myAdapter.setViewBinder(new MyViewBinder());
public class MyViewBinder implements ViewBinder {
#Override
public boolean setViewValue(View view, Object data, String text){
//Since it iterates through all the views of the item, change accordingly
if(view instanceof TextView){
((TextView)view).setTag("whatever you want");
}
}
}
I just used this exact same answer on another question (albeit slightly different) yesterday.
about getView , it works by using a method of recycling views. i will try to explain it in a simple way.
suppose you have tons of items that can be viewed . you don't want to really create tons of views too , since that would take a lot of memory . google thought of it and provide you the means to update only the views that need to be shown at any specific time.
so , if there is an empty space on the listview , it will be filled with a new view . if the user scrolls , the view that becomes hidden is recycled and given back to you on the getView , to be updated with the data of the one that is shown instead .
for example , if you scroll down , the upper view becomes hidden for the end user , but in fact it becomes the exact same view that is on the bottom .
in order to understand how to make the listview have the best performance and see in practice how and why it works as i've talked about , watch this video:
http://www.youtube.com/watch?v=wDBM6wVEO70
as for tags , i think you want to do something else , since the data itself (usually some sort of collection, like an arrayList) already knows where to update , because you get the position via the getView . if you want a specific view to update , you might be able to do so by using a hashmap that keeps upadting , which its key is the position in the collection , and the value is the associated view . on each time you go to getView , you need to remove the entry that belong to the view (if exists) and assign the new position with the view that you got/created .
Thanks for the answers. thisMayhem's answer would probably have been easier in the end, but on my quest to learn more I ended up making my own adapter according to this tutorial. I pass down the names and the IDs into the adapter and set the names as the text of the TextViews and the IDs as the tags.
I would rather go with the solution discussed in this thread. It is always the easiest to have all related data in same place and in this case you just create a class to hold all the information you will need for every item.

AlertDialog vs Spinner vs ListView

I've got what I thought was a simple android UI design problem but I've been going around in circles for a couple of days. I have a REST service that I'm downloading XML from and displaying the XML in a form in an android app. I have a web page built and am mimicking this with android, same options, same URLs being sent to the REST service whether from android or the web pages. With HTML I can easily create checkbox groups and radiobutton/dropdowns for various id/display items, so for instance, I can display a planet option as:
<select name="planet"><option value="0">Mercury</option></select>
I wanted to do something similar in android where I had a pair of values, one an id and the other the user-friendly text to display. So I decided to create an adapter using android.util.Pair:
public class PairView extends Pair<String, String> {
public PairView(String first, String second) {
super(first, second);
}
public String toString() {
return second;
}
}
public class PairAdapter extends ArrayAdapter<PairView> {
}
So now I can put my id in pair.first and what to display to the user in pair.second.
My problem comes in that some of these options will be single-selects and some will be multi-selects. In html, that's not an issue, just use a checkbox group for multi, and radio buttons/dropdowns for single selects. In android however, it seems it's not so straight forward. I tried using Spinners for the adapters, but Spinner seems to only allow single selection. AlertDialog.Builder allows for single and multi-selections, but curiously I don't see an option for using an adapter for the multi-selection, just for single selections.
I guess what I really want is a consistent look for all my options, with radio buttons displayed for single selections and checkboxes displayed for multi selections, via an adapter so I can get the id's from the Pair for the items selected.
What approach should I use? A custom spinner with code added for multi-selections? AlertDialog.Builder and somehow make it use an adapter for multi-selections? Just create a plain Alert and wrap a ListView in it? Another option that is (hopefully) simpler?
I feel like I'm missing something very basic here.
I had a similar situation in an app I was making so would share what I opted for. I had different type of questions and depending on that I removed and added things in my activity. For radio buttons I used with elements in it. For multiple choice questions I wanted a checkbox based view so I added an empty within my layout and in code added CheckBox(s) to it.
As for the caption and value, for radio buttons and checkboxes you can set display text by setText and add any object/value as a tag. So what I used to do was something like this:
CheckBox option = new CheckBox(MyActivity.this);
option.setText("Option 1");
option.setTag(10);
Later on when you get the selected option, you can simply get its tag and use its value.
This is just one way of doing it which I found simple. Hope this helps

Android ListAdapter or Possibly ListView Updating Text at Runtime

Hello folkes I have this little problem for which I cannot find a suitable answer looking around the web and on these forums. Please don't direct me to articles in which people have requested list view text color changes at run time, as I read lots of them and not found one to help me out.
I have a simple ListView that displays an array of String objects via the use of a ListAdapter.
I need to update some of ListView Strings at run time, based on their contents. Using a global reference to the list adapter used in the lists views creation I can get the contents of each list view String using following code below.
However, in addition to retrieval I'd like to be able to modify each string in turn, then put it back in the same index position and have the list view reflect the changes. How?
for (int x = 0; x <= listAdapter.getCount();x++)
{
Object o = this.listAdapter.getItem(x);
if (o.getClass().getSimpleName().equals("String"))
{
String s = (String) o;
s = modifyString(s);
//s is the string I want to modify then put back in the same place.
}//end if
}//end for
As far as I know you cannot change the items in an Adapter - unless you are using a custom Adapter (by extending a BaseAdapter etc...)
So, I think you will have to:
make sure you Adapter's constructor takes in the data structure that holds your strings
make sure your data structure is global
make the changes in that data structure whenever you need to
call myAdapter.notifyDataSetChanged();
This will tell adapter that there were changes done in the list and listview should be recreated.
And after your listview is renewed you can even take the user back to the index by:
list.setSelection(positionWhereTheUserClicked);
I hope this helps, let me know if you need more code references.
Here is some code
private ArrayList<String> results = new ArrayList<String>(); //global
private BaseAdapter searchAdapter = new BaseAdapter (results, this); //global
private void updateResults(final ArrayList<String> updatedList){
results = updatedList;
final ListView list = (ListView)findViewById(R.id.search_results);
list.setAdapter(searchAdapter);
list.setOnItemClickListener(new ListView.OnItemClickListener(){
// implementation of what happens when you click on an item //
});
searchAdapter.notifyDataSetChanged();
}
This code works just fine on my end, I hope it helps.
Just stumbled on this problem and found a solution.
I'm using a
m_ListAdapter = new SimpleAdapter(this, m_List, R.layout.option_list_row, columns, renderTo);
Each item in my listView is a manu option causing a dialog to show, once data is received through the dialog, all I have to do is just create a new SimpleAdapter with an updated ArrayList that includes the new data, then just setAdapter to the new adapter.
The ListView will update instantly.

Dynamically create CheckBoxPreferences

I am currently building out a list of rows with checkboxes dynamically using content from a web service. However, this ListView will need to do pretty much what a PreferenceActivity would accomplish.
I don't know the number of rows as the content is dynamic so I can't create each CheckBoxPreference in XML. How do I go about building a PreferenceActivity that will display an unknown number rows with a CheckBoxPreference dynamically?
I think you're looking for something like this:
public class MyPreferenceActivity extends PreferenceActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.my_preference_activity);
//fetch the item where you wish to insert the CheckBoxPreference, in this case a PreferenceCategory with key "targetCategory"
PreferenceCategory targetCategory = (PreferenceCategory)findPreference("targetCategory");
//create one check box for each setting you need
CheckBoxPreference checkBoxPreference = new CheckBoxPreference(this);
//make sure each key is unique
checkBoxPreference.setKey("keyName");
checkBoxPreference.setChecked(true);
targetCategory.addPreference(checkBoxPreference);
}
}
Well #Jodes, actually both of you are right, but the correct way of doing this would be using a ListPreference.
I would use a entire programmatic approach, from my experience it's easier to be consistent; either create an entire XML layout via code, or via XML, but mixing the 2 can be weird and you cannot alter everything set via XML...
onCreate(){
this.setPreferenceScreen(createPreferenceHierarchy());
}
public PreferenceScreen createPreferenceHierarchy(){
PreferenceScreen root = getPreferenceManager().createPreferenceScreen(this);
// category 1 created programmatically
PreferenceCategory cat1 = new PreferenceCategory(this);
cat1.setTitle("title");
root.addPreference(cat1);
ListPreference list1 = new ListPreference(this);
list1.setTitle(getResources().getString(R.string.some_string_title));
list1.setSummary(getResources().getString(R.string.some_string_text));
list1.setDialogTitle(getResources().getString(R.string.some_string_pick_title));
list1.setKey("your_key");
CharSequence[] entries = calendars.getCalenders(); //or anything else that returns the right data
list1.setEntries(entries);
int length = entries.length;
CharSequence[] values = new CharSequence[length];
for (int i=0; i<length; i++){
CharSequence val = ""+i+1+"";
values[i] = val;
}
list1.setEntryValues(values);
cat1.addPreference(list1);
return root;
}//end method
However, using this approach you will run into the platform's limitations of not having a multiple select ListPreference, and you'll probably want to implement something else.
I found this solution, which works great. You'll have to read the comments to find clues about how to debug the code though...
You need a ListView for that, a PreferenceActivity. As discussed in this link, PreferenceActivity should only be used for actually saving preferences.
Instead you could either create a simple dialog with single or multiple choice options:
http://developer.android.com/guide/topics/ui/dialogs.html
Or use a ListView as in the API examples Google provides, they give a simple example:
http://hi-android.info/docs/resources/samples/ApiDemos/src/com/example/android/apis/view/List10.html
Use PreferenceFragmentCompat from Preference Compat Library
compile 'com.android.support:preference-v7:23.4.0'
Check this article for the implementation details https://medium.com/#arasthel92/dynamically-creating-preferences-on-android-ecc56e4f0789#.71ssvjses

Problem with list activity

I have implmented pagination and it display 5 records per page. Now suppose I am on page 3 and click 3'rd element then 3'rd element of page-1 is selected.
I am not able to figure out problem as I always create new list object while setting data.
I used below code
temp = new ArrayList();
this.someListAdapter = new SomeListAdapter(this, R.layout.row_facet,temp);
setListAdapter(this.someListAdapter );
Below is signature of SomeListAdapter class.
public class SomeListAdapter extends ArrayAdapter<VoNeighborhood> {
}
Please help....
There really aren't enough details here about how you do pagination with your ListView.
So I might guess you're overriding onListItemClick and using the position variable it sends you, but you then don't take into account the page you're on?
Alternatively, just don't use pagination as you have an infinite canvas to scroll your list within — I don't think I've recall seeing an Android app so far that uses pagination!

Categories

Resources