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.
Related
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!
I am trying to add an image to my ListView to make it look more like a button. I would like the images to be a little smaller, maybe 60% of current. And the images to lign up nicely on the right in a column. Here is a screen of what I currently have:
and here is my list view xml:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="fill_parent"
android:padding="10dp"
android:textSize="16sp"
android:layout_width="match_parent"
android:drawableRight="#drawable/arrow_button"
>
</TextView>
any idea what I am doing incorrectly?
The ListView that contains this TextView is defined like this:
One note, the way I create and work with my Lists is with the ListAdapter, using code like this:
Question q = new Question ();
q.setQuestion( "This is a test question and there are more than one" );
questions.add(q);
adapter = new ArrayAdapter<Question>( this, R.layout.questions_list, questions);
setListAdapter(adapter);
Thanks!
Ahh. You are doing the correct thing using a compound drawable. Not sure if there is a better way to maybe have the spacing in your compound drawable expand, but I know this'll work.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent">
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:padding="10dp"
android:textSize="16sp"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true" />
<View
android:layout_height="64dip"
android:layout_width="64dip"
android:background="#drawable/arrow_button"
android:layout_centerVertical="true"
android:layout_alignParentRight="true" />
</RelativeLayout>
Basically just pointing out using the align parent right and left. You may want to add some margins or padding to them. Also make sure to vertically center your elements.
With the comment and advice that Frank Sposaro gave, you will be able to position your views correctly.
For your next problem, I advice you to make your own adapter similar to this:
private class CustomAdapter extends ArrayAdapter<Question> {
private LayoutInflater mInflater;
public CustomAdapter(Context context) {
super(context, R.layout.row);
mInflater = LayoutInflater.from(context);
}
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.row, null);
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.mTextView);
holder.image = (ImageView) convertView.findViewById(R.id.mImage);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
//Fill the views in your row
holder.text.setText(questions.get(position).getText());
holder.image.setBackground... (questions.get(position).getImage()));
return convertView;
}
}
static class ViewHolder {
TextView text;
ImageView image;
}
In your onCreate:
ListView mListView = (ListView) findViewById(R.id.mListView);
mListView.setAdapter(new CustomAdapter(getApplicationContext(), questions));
Another example for a ListView with an Adapter can be found here
I'd like to implement a Listview in android in which I have the possibility to enable a delete mode, in which the user can select the entries to delete. It should be similar to the message application in android.
I already have a ListActivity which has an icon on the left and text on the right side. I now like to add a CheckBox floating on the right side of the list entry. The ListActivity is listed in another question by a friend of mine: android listactivity background color .
The layout should be:
Left Picture
Center List item
Right Checkbox for delete selection
How can I achieve this? Is there a standard ListView item in the framework I could use?
I guess you want a CheckBox to appear(only) when is time to delete items from the ListView. Assuming you use the layout from the other question:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:background="#color/darkbluelogo" >
<ImageView android:id="#+id/list_image"
android:layout_width="48dip"
android:layout_height="48dip"
android:contentDescription="#id/list_image"
/>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="fill_parent"
android:padding="5dp"
android:background="#color/darkbluelogo"
android:scrollingCache="false"
android:cacheColorHint="#00000000" >
<TextView
android:id="#+id/title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#+id/title" >
</TextView>
<TextView
android:id="#+id/datetime"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#+id/datetime" >
</TextView>
</LinearLayout>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone" />
</LinearLayout>
When the ListView starts the CheckBox will not be present and the content TextViews will occupy all the space. Add a flag in the getView method of your adapter that will signal that the CheckBox must be shown(here you will set the CheckBox's visibility from the layout to visible). When its time to delete items modify the flag and then call notifyDataSetChanged() so the ListView redraws its children, this time with the CheckBox present.
Note:
You'll have to store the status of the CheckBoxes yourself.
First of all you need a custom layout for your list entries. A simple RelativeLayout including an ImageView , a TextView and a CheckBox should be enough.
Then you might want to build your own custom adapter which can extend BaseAdapter (or SimpleAdapter or CursorAdapter or ArrayAdapter or...). The adapter will bind the list's data to your custom layout. If for example your data is contained in a Cursor it will look like:
private class MyCustomAdapter extends CursorAdapter {
public MyCustomAdapter(Context context) {
super(context, null);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
//Return a list item view
return getLayoutInflater().inflate(R.layout.my_custom_list_item_layout, parent, false);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
//Get views from layout
final ImageView imageView = (ImageView) view.findViewById(R.id.list_item_image);
final TextView textView = (TextView) view.findViewById(R.id.list_item_text);
final CheckBox checkBox = (CheckBox) view.findViewById(R.id.list_item_checkbox);
//Get data from cursor
final String text = cursor.getString(...);
//Add listener to the checkbox
checkBox.setOnClickListener(new OnClickListener() {...});
//Bind data
textView.setText(text);
}
}
I have a ListView (with an Adapter of my own) where I'd like to add a delete button by swaping an item on the ListView (like on iPhones).
I really don't know how to do it and where to start ...
Could you please give me some hints ?
Thanks
What you want to implement is a custom ListView. You need a layout for your row, here's an example
res/layout/row.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#android:color/transparent">
<TextView android:id="#+id/Browse_DateTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/transparent" />
<ImageButton android:id="#+id/delete"
android:layout_width="wrap_content"
android:layout_height="fill_parent" />
</LinearLayout>
Then you need to overide the getView() method of your adapter, a little like this:
setListAdapter(new ArrayAdapter<Object>(this, R.layout.row, R.id.Browse_DateTime, ourRows) {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)BrowseActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.row, null);
}
TextView time = (TextView) v.findViewById (R.id.Browse_DateTime);
time.setText(ourRows[position].dateTime);
ImageButton delete = (ImageButton) v.findViewById(R.id.delete);
delete.setFocusable(false);
delete.setImageDrawable(BrowseActivity.this.getResources().getDrawable(R.drawable.deletebutton));
delete.setOnClickListener(BrowseActivity.this);
delete.setId(position);
return v;
}
};)
Best regards.
PS: this is cut&paste from my code, BrowseActivity is just the name of the activity this code resides in, R.layout.row is my row.xml file, you name it any which way, just put it in /res/layout/, and if your delete button is an imagebutton, you DO need the delete.setFocusable(false); (try it without and see why).
I am developing an android application which contains a ListAtivity class and get it is data as follow :
ArrayAdapter<Item> ara=new MyArrayAdapter(this,_items);
setListAdapter(ara);
And I defined MyArrayAdapter :
....
public MyArrayAdapter(Activity context, List<BirthdayContact> list) {
super(context,R.layout.list_row,0,list);
//super(context, R.layout.birthday_list, list);
this.context = context;
this.list = list;
}
public View getView(int position, View convertView, ViewGroup parent) {
View view = null;
if (convertView == null) {
LayoutInflater inflator = context.getLayoutInflater();
view = inflator.inflate(R.layout.birthday_list_row, null);
final ViewHolder viewHolder = new ViewHolder();
viewHolder._cName= (TextView) view.findViewById(R.id.contact_name);
viewHolder._cImage = (ImageView) view.findViewById(R.id.contact_image);
viewHolder._cbirthDay=(TextView)view.findViewById(R.id.contact_birthday_remained);
view.setTag(viewHolder);
}
......
But the problem with this way is that you cant only assign each row`s template and you cant have other widget on list view which are not part of list of data. I mean I want to have a say a TextView which shows messages to user, and below that I show the list of rows.
Can you help me please?
If you want a different layout than a simple ListView you have the option of setting the content view to a layout file like this:
setContentView(R.layout.layout_with_diferrent_views); // call this on the onCreate() method
where R.layout.layout_with_different_views could be a xml layout like this:
<?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="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
Because you extends ListActivity you must have in the layout a ListView element with the id #android:id/list. Of course you can have a more complex layout than the one above as long as you have a ListView element with the id #android:id/list
You should consider using a listHeader : lv.addHeaderView(findViewById(R.id.header));
This has to be done in your onCreate method in your activity, and you must provide a widget with the id header.
If you want other components in activity.Then better consider Normal Activity instead ListActivity.