I have a ListView, titled myListView, that I would like to populate with 3 LinearLayout elements, titled layout1.xml, layout2.xml, and layout3.xml. All 3 LinearLayout elements are very similar; here is one of them:
<?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="match_parent"
android:orientation="horizontal" >
<TextView
android:layout_width="0dip"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="Los Angeles" />
<TextView
android:layout_width="0dip"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="California" />
</LinearLayout>
My goal is to populate a the ListView (myListView) with these three LinearLayout elements. Does anyone know how I would go about doing this?
First of all, if all three linear layouts are alike, I suggest you to only use one.
Anyway, you have to use a custom adapter for your ListView. You create a class that extends ArrayAdapter for example. If you are not familiar with custom adapters, I suggest you take a look here.
In your getView method, you practically have to inflate a different *.xml, depending on your cell position. Thus:
#Override
puclic View getView (int position, View view, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
switch (position) {
case 0: view = inflater.inflate(R.layout.my_layout_1, null, true);
//rest of my code
break;
case 1: view = inflater.inflate(R.layout.my_layout_2, null, true);
//rest of my code
break;
case 2: view = inflater.inflate(R.layout.my_layout_3, null, true);
//rest of my code
break;
default: break;
//rest of my code
return view;
}
As DDsix points out, you really should be using one layout that can handle whatever data you want, and then populate the fields using an adapter. If I had to guess, I'd bet the only difference between your layouts is the text for the city and state.
The documentation explains how to do this very well: http://developer.android.com/guide/topics/ui/layout/listview.html
Basically, you should create a private List<Location> mLocations; variable to hold your locations (Location would be a simple class you define with strings to hold city and state). Then, you can use the following in your adapter.
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
LayoutInflater inflater = context.getLayoutInflater();
View view = inflater.inflate(R.layout.my_layout_1, parent);
Location location = mLocationList.get(position);
TextView cityView = view.findViewById(R.id.city_view);
TextView stateView = view.findViewById(R.id.state_view);
cityView.setText(location.getCity());
cityView.setText(location.getState());
return view;
}
Related
I have a spinner. If selected item is (e.g) 1, then add EditText with button. I used switch method to check item_name. What you recommend in adding edittext with button? Is it a good way to create new layout? How can i add layout to screen?
Try to use OnItemSelectedListener.
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
// your code here
}
#Override
public void onNothingSelected(AdapterView<?> parentView) {
// your code here
}
});
Inside your initial layout create a container layout to inflate with your desired generated views.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>
</RelativeLayout>
Then create the separate layouts (your_layout) that you want to generate upon spinner selection. When that happens, use a layout inflator to replace the container with the layout you want.
LayoutInflater inflater = LayoutInflater.from(context);
View layout = inflater.inflate(R.layout.your_layout, null, false);
View container = inflater.inflate(R.id.container, null, false);
container.addView(layout);
I'm using a custom layout for a Spinner DropDownview, it has a brown background with white letters. There are some white stripes appearing at the bottom of the view1, that I want to remove but I don't know how neither why they are appearing;
here are the code that I'm using for the spinner_dropdown_item:
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#android:id/text1"
style="?android:attr/spinnerDropDownItemStyle"
android:layout_width="match_parent"
android:layout_height="#dimen/dropdownListPreferredItemHeight"
android:background="#color/marrom"
android:ellipsize="marquee"
android:gravity="center_vertical"
android:minHeight="#dimen/txt_min_height"
android:paddingEnd="#dimen/md_keylines"
android:paddingStart="#dimen/md_keylines"
android:singleLine="true"
android:textAllCaps="true"
android:textColor="#color/white"
android:textSize="#dimen/text_subtitle"
tools:text="spinner dropdown item" />
and the getDropdownView inside the spinner adapter:
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
T element = elements.get(position);
convertView = LayoutInflater.from(parent.getContext()).inflate(getDropdownLayout(), parent, false);
final TextView textView = (TextView) convertView;
textView.setText(getDisplayName(element));
return textView;
}
where the function getDropdownLayout returns the layout above
After some research, I stumbled upon a suggestion:spinner with a rectangular border.
Create 9 patch image(Rectangle Box) which helps you to set the spinner with different resolution.
After creating 9 patch image use it as a background of the Spinner.
Here is a link that makes creating that 9pacth image simple:http://inloop.github.io/shadow4android/
Here is my example:
I know how to customize the spinner. In my case it is a little bit different. I cannot modify my code more than I have now. Normally, I am able to make spinner that is reachable from all activities in my app.
I am trying to put icon along the textview in the spinner drop down.
Here the code I have;
Spinner.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="fill_parent" >
<Spinner
android:id="#+id/spinner"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:drawSelectorOnTop="true"
android:spinnerMode="dialog"
android:prompt="#string/language_prompt" />
spinner_row.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/TextView01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:addStatesFromChildren="true"
android:gravity="center_horizontal"
android:padding="5dp"
android:textColor="#FFFFFF"
android:textSize="17sp" >
</TextView>
<!-- Here I cannot use Relative layout. If I use it gives error like [java.lang.ClassCastException: android.widget.ImageView cannot be cast to android.widget.TextView]. Without layout I cannot implement ImageView. I am stuck here.
My activity class;
public class Base_Activity extends Activity {
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
//int flags = R.array.flags;
final Spinner spinner = (Spinner) menu.getItem(0).getActionView()
.findViewById(R.id.spinner);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
this, R.array.languages, R.layout.spinner_row);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
What I want is to make is custom Adapter so that I can put image along the textview in spinner list. I am not able to make normal way that I checked in many tutorials. I think it's because I am creating spinner in onCreateOptionsMenu() constructor.
u can take a look at this tutorial on AndroidHive
http://www.androidhive.info/2013/11/android-working-with-action-bar/
code snippet
// Spinner title navigation data
navSpinner = new ArrayList<SpinnerNavItem>();
navSpinner.add(new SpinnerNavItem("Local", R.drawable.ic_location));
navSpinner
.add(new SpinnerNavItem("My Places", R.drawable.ic_my_places));
navSpinner.add(new SpinnerNavItem("Checkins", R.drawable.ic_checkin));
navSpinner.add(new SpinnerNavItem("Latitude", R.drawable.ic_latitude));
// title drop down adapter
adapter = new TitleNavigationAdapter(getApplicationContext(),
navSpinner);
getView() and getDropDownView() from TitleNavigationAdapter
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater)
context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.list_item_title_navigation, null);
}
imgIcon = (ImageView) convertView.findViewById(R.id.imgIcon);
txtTitle = (TextView) convertView.findViewById(R.id.txtTitle);
imgIcon.setImageResource(spinnerNavItem.get(position).getIcon());
imgIcon.setVisibility(View.GONE);
txtTitle.setText(spinnerNavItem.get(position).getTitle());
return convertView;
}
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater)
context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.list_item_title_navigation, null);
}
imgIcon = (ImageView) convertView.findViewById(R.id.imgIcon);
txtTitle = (TextView) convertView.findViewById(R.id.txtTitle);
imgIcon.setImageResource(spinnerNavItem.get(position).getIcon());
txtTitle.setText(spinnerNavItem.get(position).getTitle());
return convertView;
}
Download that code and u r good to go
I have a ListView that uses a custom adapter. Each element in the ListView contains a RadioButton and a TextView.
Here is my adapter, it takes an ArrayList of Employees (An object that currently only contains a name):
public class EmployeeAdapter extends ArrayAdapter<Employee> {
private ArrayList<Employee> listEmployees;
// Give the adapter the context and layout we are operating it, as well as a list of employees to put in the list.
public EmployeeAdapter(Context context, int layout, ArrayList<Employee> listEmployees) {
super(context, layout, listEmployees);
this.listEmployees = listEmployees;
}
// We override the basic getView function since our list is custom.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
// If there is nothing left to put in the view, inflate the view in the rowemployee layout.
if (v == null){
LayoutInflater vi;
vi = LayoutInflater.from(getContext());
v = vi.inflate(R.layout.rowemployees, null);
}
Employee i = listEmployees.get(position);
// Check if there's still an employee in the list.
if (i != null){
TextView name = (TextView) v.findViewById(R.id.text_employeename);
name.setText(i.getName());
}
// Alternate row colors.
if (position % 2 == 0) {
v.setBackgroundColor(Color.parseColor("#FFFFFF"));
} else {
v.setBackgroundColor(Color.parseColor("#e5fff4"));
}
return v;
}
}
Here is the listview declaration in my XML layout:
<ListView android:id="#+id/employees_list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingLeft="2dp"
android:paddingRight="1dp"
android:background="#drawable/borderlist"
android:choiceMode="singleChoice"
android:listSelector="#48ad82"
android:layout_below="#id/employees_header">
</ListView>
And here is the layout of every item of the ListView:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/row_employee"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingTop="13dp"
android:paddingBottom="13dp"
android:descendantFocusability="blocksDescendants">
<RadioButton android:id="#+id/radio_employee"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:focusable="false"/>
<TextView
android:id="#+id/text_employeename"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:layout_toRightOf="#id/radio_employee"
android:layout_marginTop="3dp"
android:layout_marginLeft="5dp"
android:focusable="false" />
</RelativeLayout>
I input a bunch of Employee objects into an ArrayList, which I push to the adapter, and then I set a setOnItemClickListener on the list. The listener contains this code:
OnItemClickListener onItemClickListener_employee
= new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id){
Toast.makeText(getApplicationContext(), String.valueOf(view.isSelected()) , Toast.LENGTH_SHORT).show();
}
};
view.isSelected() always returns false. Why? I've been trying to figure out how to select an element on a list containing something else than just a TextView for a couple of hours, and the SDK documentation isn't very helpful, this is getting old.
When I press on the list's items, it seems like the TextView or the RadioButton get pressed instead. Shouldn't focusable="false" prevent this ( Android custom ListView unable to click on items )?
To get the item chosen, add the following method to your adapter (untested code):
public Employee getItemAt(int position){
return listEmployees.get(position);
}
Then in your handler, pass the position to the new adapter method above
public void onItemClick(AdapterView<?> parent, View view, int position, long id){
Employee e = adapter.getItemAt(position); //or whatever your adapter instance is named
Toast.makeText(getApplicationContext(), e.getName(), Toast.LENGTH_SHORT).show();
}
Since the view is just for displaying data, you really don't care about the view itself (unless you want to remove it, hilight it, etc).
I have a problem with adding a listview as a header in my listview (go go redundancy). The code is working, however only the first item shows up in the header. The body looks fine.
listView = (ListView) findViewById(R.id.default_list_view);
header = (ListView) getLayoutInflater().inflate(R.layout.savings_overview_header_list, null, false);
HeaderAdapter hAdapter = new HeaderAdapter(getLayoutInflater());
hAdapter.addItem("1");
hAdapter.addItem("2");
hAdapter.addItem("3");
header.setAdapter(hAdapter);
for (Policy p : saving.getPolicies()) {
adapter.addItem(p);
}
listView.addHeaderView(header);
listView.setAdapter(adapter);
headerView:
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/default_list_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:cacheColorHint="#00000000"
android:divider="#drawable/list_divider"
android:dividerHeight="2px"
android:fadingEdge="none"
android:fitsSystemWindows="true"
android:footerDividersEnabled="false"
android:headerDividersEnabled="false"
android:listSelector="#drawable/list_item_background_selected"
>
</ListView>
I have tried wrapping the ListView in a vertical LinearLayout but no cigar there either :(
hAdapter
private static class HeaderAdapter extends BaseAdapter {
private final LayoutInflater inflater;
protected ArrayList<String> data = new ArrayList<String>();
public HeaderAdapter(LayoutInflater inflater) {
this.inflater = inflater;
}
public void addItem(String s) {
data.add(s);
}
public View getView(int position, View convertView, ViewGroup parent) {
final PolicyViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.savings_overview_header_item, parent, false);
holder = new PolicyViewHolder();
holder.header = (TextView) convertView.findViewById(R.id.list_item_header);
holder.subHeader = (TextView) convertView.findViewById(R.id.list_item_subheader);
holder.img = (ImageView) convertView.findViewById(R.id.list_item_img);
convertView.setTag(holder);
} else {
holder = (PolicyViewHolder) convertView.getTag();
}
String s = data.get(position);
holder.header.setText(s);
holder.subHeader.setText(s);
holder.img.setImageResId(R.drawable.test);
return convertView;
}
public int getCount() {
return data.size();
}
public Object getItem(int position) {
return data.get(position);
}
public long getItemId(int position) {
return position;
}
private static class PolicyViewHolder {
TextView header;
TextView subHeader;
ImageView img;
}
}
header_item
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp" >
<ImageView
android:id="#+id/list_item_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:src="#drawable/ic_launcher"/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginRight="10dp"
android:layout_marginLeft="5dp"
android:layout_toLeftOf="#+id/list_item_value"
android:layout_toRightOf="#+id/header_image"
android:orientation="vertical" >
<TextView
android:id="#+id/list_item_header"
style="#style/header_list_header"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/list_item_subheader"
style="#style/list_header_sub_header"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="sub header" />
</LinearLayout>
</RelativeLayout>
i have tried to wrap a linearlayout="vertical" around this one as well
You have to tell the parent view how to stack your elememnts. This is necessary for parents like a LinearLayout. If you're going to have such an adapter, you need to have a parent to contain these things, UNLESS its a single view.
Update
Whenever you want to do processing with the views in a ListView you
need to create a custom adapter that will handle your logic
implementation and pass that information to the views as necessary.
A custom adater would inflate the views piece by piece, this can be
dynamic of fixed.
I suspect that your problem relates to Android simply not knowing how to handle the two levels of "scrollability" this design implies. Think about it - If the user drags over the header, how is Android supposed to know whether they mean to scroll the outer list or the list within the header? I once recall Romain Guy making the same point about placing ListViews inside ScrollViews, it's slightly meaningless.
What's probably happening is that Android makes the header big enough to simply display a single header list item and it assumes any dragging gesture by the user should apply to the outer list.
Generally, I think what you've described sounds like a bad design choice and you need to take a step back.
What functionally do you want this UI to do?
If it's simply that you want to display two sets of content within a single list, then this is a problem you need to solve within the ListAdapter implementation you're using. e.g. Take a look Jeff Sharkey's blog post on his SeparatedListAdapter.
Make a LinearLayout with vertical orientation and add both ListViews there. That should fix your hiccup.
Cheers.