Is there anyway to add two text views or strings inside of the Actionbar Spinner?
Similar to how the Android GMAIL app does it.
You could use a custom ArrayAdapter:
public class spinnerAdapter extends ArrayAdapter {
private LayoutInflater inflater;
public spinnerAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
inflater = LayoutInflater.from(context);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null){
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.spinner_text_layout, null);
holder.text1 = (TextView)convertView.findViewById(R.id.spinnerText1);
holder.text2 = (TextView)convertView.findViewById(R.id.spinnerText2);
convertView.setTag(R.layout.spinner_text_layout, holder);
} else{
holder = (ViewHolder)convertView.getTag(R.layout.spinner_text_layout);
}
holder.text1.setText("Position: " );
holder.text2.setText(position);
return convertView;
}
public View getDropDownView(int position, View convertView, ViewGroup parent) {
ViewHolder2 holder;
if(convertView == null){
holder = new ViewHolder2();
convertView = inflater.inflate(R.layout.spinner_text_layout, null);
holder.text1 = (TextView)convertView.findViewById(R.id.spinnerText1);
holder.text2 = (TextView)convertView.findViewById(R.id.spinnerText2);
convertView.setTag(R.layout.spinner_text_layout, holder);
} else{
holder = (ViewHolder2)convertView.getTag(R.layout.spinner_text_layout);
}
holder.text1.setText("Position: " );
holder.text2.setText(position);
return convertView;
}
static class ViewHolder{
TextView text1;
TextView text2;
}
static class ViewHolder2{
TextView text1;
TextView text2;
}
}
spinner_text_layout.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:id="#+id/spinnerText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="18dp"
android:layout_marginTop="16dp"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/spinnerText2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/textView1"
android:layout_alignParentRight="true"
android:layout_marginRight="23dp"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium" />
ActionBar.setListNavigationCallbacks(...)
It's just a SpinnerAdapter. If you are familiar with adapters, you can make your own class extending BaseAdapter and have a custom layout. If you aren't familiar with adapters, I suggest you watch The World of ListView.
Related
I have Listview that contains a Textview, I populate data from sqlite inside them , now I want to change the textview background color for each row based on the value in each one.
I couldn't do it , can anybody help me for how to get each textview from the listview ??
Edit :
Here is my code to populate the listview:
sql = new SqlCommands(getApplicationContext());
Fields = new String[]{SqlCommands.Group, SqlCommands.Subject, SqlCommands.Body, SqlCommands.DateTime};
int [] Dview = new int []{R.id.grop, R.id.sbj,R.id.bdy,R.id.DT};
Cursor c = sql.GetData();
Adpt = new SimpleCursorAdapter(getApplicationContext(),R.layout.items, c , Fields, Dview ,0 );
NotiLst.setAdapter(Adpt);
this is the XML file for the items :
<?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="match_parent"
android:orientation="horizontal"
android:background="#drawable/grp_shap" >
<ImageView android:id="#+id/Prio"
android:layout_width="32dip"
android:layout_height="32dip"
/>
<TextView
android:id="#+id/grop"
android:layout_width="64sp"
android:layout_height="40sp"
android:layout_alignBottom="#+id/Prio"
android:layout_alignParentLeft="true"
android:text="S"
android:textSize="12sp" />
<TextView
android:id="#+id/DT"
android:layout_width="wrap_content"
android:layout_height="14sp"
android:layout_alignParentRight="true"
android:layout_alignTop="#id/title"
android:gravity="right"
android:text="Date Rec"
android:layout_marginRight="5dip"
android:textSize="12sp"
/>
<TextView
android:id="#+id/bdy"
android:layout_width="fill_parent"
android:layout_height="28sp"
android:layout_below="#+id/DT"
android:layout_toLeftOf="#+id/hi"
android:layout_toRightOf="#+id/Prio"
android:text="Body"
android:textSize="12sp" />
<TextView
android:id="#+id/sbj"
android:layout_width="fill_parent"
android:layout_height="12sp"
android:layout_alignLeft="#+id/bdy"
android:layout_alignParentTop="true"
android:layout_alignRight="#+id/bdy"
android:fontFamily="sans-serif"
android:text="Subject"
android:textSize="12sp" />
<ImageView
android:id="#+id/hi"
android:layout_width="20dip"
android:layout_height="26dip"
android:layout_alignLeft="#+id/DT"
android:layout_below="#+id/DT"
android:layout_marginLeft="15dp"
android:src="#drawable/highprio" />
</RelativeLayout>
and I have a listview on the activity_mail layout which populated whith this items.
I want to change the color for the textview with id grop based on the value inserted on it
You should use a custom adapter:
public class MyAdapter extends BaseAdapter {
private static class ViewHolder {
public final TextView mTv;
}
private final Context mContext;
private final List<String> mList; //you can change this to String array
public MyAdapter (Context context, List<String> list) {
this.mContext = context;
this.mList= list;
}
#Override
public int getCount() {
return mList.size();
}
#Override
public String getItem(int position) {
return mList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder h;
final String string = mList.get(position);
if (convertView == null) {
convertView = View.inflate(mContext, R.layout.item_listview, null);
h = new ViewHolder();
h.mTv= (TextView) convertView .findViewById(R.id.mTvRes);
convertView.setTag(h);
} else {
h = (ViewHolder) convertView.getTag();
}
h.mTv.setText....
h.mTv.setTextColor....
h.mTv.setBackground....
return convertView;
}
}
in your activity:
List<String> list = Arrays.asList(Fields);
MyAdapter adapter = new MyAdapter(this, list);
NotiLst.setAdapter(adapter);
I didn't checked it and you maybe need to do some changes but it should work.
If you have something like this:
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if(convertView == null) {
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(resource, parent, false);
viewHolder = new ViewHolder();
viewHolder.label = (TextView) convertView.findViewById(android.R.id.text1);
viewHolder.label.setBackground(getResources().getColor(color.white));
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.label.setText(activitiesList.get(position).getName());
return convertView;
}
Im working on simple feedreader app. in my main activity i have listview that show all items . in each row i have imagebutton for save that item and when user click on that the image of imagebutton must be change(like fav icon on twitter) but it does not change ! After scrolling changes are observed !
this is my row layout .
<?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="match_parent"
android:descendantFocusability="blocksDescendants" >
<TextView
android:id="#+id/tvListViewItemTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginRight="15dp"
android:layout_marginTop="15dp"
android:text="#string/listview_item_title"
android:textSize="25dp" />
<TextView
android:id="#+id/tvListViewItemText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="#+id/tvListViewItemTitle"
android:layout_below="#+id/tvListViewItemTitle"
android:layout_marginTop="20dp"
android:text="#string/listview_item_text"
android:textSize="18dp" />
<TextView
android:id="#+id/tvListViewItemTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="#+id/tvListViewItemText"
android:layout_below="#+id/tvListViewItemText"
android:layout_marginTop="22dp"
android:paddingTop="5dp"
android:text="#string/listview_item_time" />
<ImageButton
android:id="#+id/ibListViewItemSave"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignTop="#+id/tvListViewItemTime"
android:layout_marginLeft="20dp"
android:paddingTop="11dp"
android:src="#drawable/icon_save_story_2x"
android:background="#null" />
and this is my custom adapter class.
public class FeedListAdapter extends ArrayAdapter<FeedItem> {
private final Activity context;
private final List<FeedItem> list;
public FeedListAdapter(Activity context, List<FeedItem> list) {
super(context, R.layout.feed_listview_item_type1, list);
this.context = context;
this.list = list;
}
static class ViewHolder {
TextView tvTitle;
TextView tvText;
TextView tvTime;
ImageButton ibSave;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
if (rowView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(R.layout.feed_listview_item_type1, parent,false);
// configure view holder
ViewHolder holder = new ViewHolder();
holder.tvTitle = (TextView)rowView.findViewById(R.id.tvListViewItemTitle);
holder.tvText = (TextView)rowView.findViewById(R.id.tvListViewItemText);
holder.tvTime = (TextView)rowView.findViewById(R.id.tvListViewItemTime);
holder.ibSave = (ImageButton)rowView.findViewById(R.id.ibListViewItemSave);
rowView.setTag(holder);
}
// fill data
ViewHolder holder = (ViewHolder) rowView.getTag();
final FeedItem feedItem = list.get(position);
holder.tvTitle.setText(feedItem.getTitle());
holder.tvText.setText(feedItem.getText());
holder.tvTime.setText(feedItem.getTime());
if(feedItem.isSave()) holder.ibSave.setImageResource(R.drawable.icon_saved_story_2x);
else holder.ibSave.setImageResource(R.drawable.icon_save_story_2x);
final String msg = " "+(position+1);
holder.ibSave.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
if(feedItem.isSave()){
feedItem.setSave(false);
Toast.makeText(context,
msg+"deleted", Toast.LENGTH_SHORT).show();
//holder.ibSave.setImageResource(R.drawable.icon_save_story_2x);
}else{
feedItem.setSave(true);
Toast.makeText(context,
msg+"saved", Toast.LENGTH_SHORT).show();
//holder.ibSave.setImageResource(R.drawable.icon_saved_story_2x);
}
}
});
return rowView;
}
}
Call notifyDataSetChanged in your onClick after the if else.
At present the FeedListAdapter does not realize that you have made some changes to the list
I created my own custom adapter that extends Array Adapter:
public class AdapterGeoArea extends ArrayAdapter<GeoArea>{
private Context _context;
private int resource;
private ArrayList<GeoArea> _myGeoArea;
public AdapterGeoArea(Context context, ArrayList<GeoArea> myGeoArea) {
super(context, 0, myGeoArea);
_context = context;
_myGeoArea = myGeoArea;
}
public int getCount() {
return _myGeoArea.size();
}
public View getView(int position, View convertView, ViewGroup parent) {
LinearLayout GeoAreaView;
if (convertView == null) {
GeoAreaView = new LinearLayout(_context);
LayoutInflater li = LayoutInflater.from(_context);
convertView = li.inflate(R.layout.layout_geo_areas, null);
}
else {
GeoAreaView = (LinearLayout) convertView;
}
GeoArea curGeoArea = _myGeoArea.get(position);
TextView name = (TextView) GeoAreaView.findViewById(R.id.txtGeoAreaName);
name.setText(curGeoArea.name);
return convertView;
}
static class ViewHolder {
TextView name;
RelativeLayout childContainer;
}
#Override
public Filter getFilter() {
return null;
}
}
And here is how I am using it in my main:
public class ActivityGeoAreas extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_geo_areas);
GeoArea.searchTerm = "Bar & Grill";
GeoArea torontoArea = new GeoArea("cityOfToronto");
ArrayList<GeoArea> testList = new ArrayList<GeoArea>();
testList.add(torontoArea);
AdapterGeoArea adapter = new AdapterGeoArea(this, testList);
ListView lv = (ListView) findViewById(R.id.textGeoArea);
lv.setAdapter(adapter);
}
}
Everything seem to be fine except for this line:
TextView name = (TextView) GeoAreaView.findViewById(R.id.textGeoArea);
And here is how I defined my layout:
<RelativeLayout 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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".ActivityGeoAreas" >
<TextView
android:id="#+id/textGeoArea"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="Choose Area"
android:textAppearance="?android:attr/textAppearanceLarge" />
<LinearLayout
android:id="#+id/LinearLayoutGeoAreas"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/textGeoArea"
android:layout_below="#+id/textGeoArea"
android:orientation="vertical" >
<ListView
android:id="#+id/listViewGeoArea"
android:layout_width="wrap_content"
android:layout_height="match_parent" >
</ListView>
</LinearLayout>
</RelativeLayout>
It simply can't find the TextView textGeoArea and this line become null, what am I doing wrong?
Change this
TextView name = (TextView) GeoAreaView.findViewById(R.id.txtGeoAreaName);
to
TextView name = (TextView) convertView.findViewById(R.id.txtGeoAreaName);
I guess you have got confused.
Move textview to a new layout list_item.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="match_parent" >
<TextView
android:id="#+id/textGeoArea"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="14dp"
android:text="Choose Area"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
Now change your getView as below
LayoutInflater inflater;
public AdapterGeoArea(Context context, ArrayList<GeoArea> myGeoArea) {
super(context, 0, myGeoArea);
_context = context;
_myGeoArea = myGeoArea;
inflater = LayoutInflater.from(context); // initialize inflater
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.list_row,parent,false);
holder = new ViewHolder();
holder.tv = (TextView)convertView.findViewById(R.id.textGeoArea);
holder.setTag(convertView);
}
else {
holder = (ViewHolder) convertView.getTag();
}
GeoArea curGeoArea = _myGeoArea.get(position);
holder.tv.setText(curGeoArea.name);
return convertView;
}
static class ViewHolder // use a view holder for smooth scrolling an performance
{
TextView tv;
}
On the first pass, GeoAreaView is a childless LinearLayout since you just created it. convertView is the View initialized your layout which holds the TextView. So you need to use that to find the TextView.
TextView name = (TextView) convertView.findViewById(R.id.txtGeoAreaName);
I see you have a ViewHolder but you don't appear to be using it. You may want to take a little time and go through a good tutorial on using ListView.
This guy usually seems to have good tutorials
I am developing an application where navigation is done by using the spinner on the action bar. Spinner items needed to include icons as well so I created custom layouts for that.The problem is that spinner is too wide with respect to its items. I am using ActionBarSherlock. The codes I wrote so far:
navigation_list_item.xml:
<?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="match_parent"
android:layout_gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:id="#+id/icon"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:padding="4dip"/>
<TextView
android:id="#+id/title"
style="?attr/spinnerItemStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:singleLine="true"
android:layout_gravity="center_vertical"/>
</LinearLayout>
navigation_list_dropdown_item.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:layout_gravity="center_vertical"
android:orientation="horizontal" >
<ImageView
android:id="#+id/icon"
android:layout_width="wrap_content"
android:layout_height="?attr/dropdownListPreferredItemHeight"
android:adjustViewBounds="true"
android:padding="4dip"/>
<TextView
android:id="#+id/title"
style="?attr/spinnerDropDownItemStyle"
android:layout_width="match_parent"
android:layout_height="?attr/dropdownListPreferredItemHeight"
android:ellipsize="marquee"
android:singleLine="true" />
</LinearLayout>
NavigationListAdapter.java:
public class NavigationListAdapter extends BaseAdapter{
private Drawable[] mIcons;
private String[] mTitles;
private Context mContext;
private LayoutInflater mInflator;
public NavigationListAdapter(Context context, Drawable[] icons, String[] titles){
mContext = context;
mInflator = (LayoutInflater)mContext.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
mIcons = icons;
mTitles = titles;
}
#Override
public int getCount() {
return mTitles.length;
}
#Override
public Object getItem(int position) {
return mTitles[position];
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null){
convertView = mInflator.inflate(R.layout.navigation_list_item, parent, false);
holder = new ViewHolder();
holder.icon = (ImageView)convertView.findViewById(R.id.icon);
holder.title = (TextView)convertView.findViewById(R.id.title);
convertView.setTag(holder);
}else{
holder = (ViewHolder)convertView.getTag();
}
holder.title.setText(mTitles[position]);
holder.icon.setImageDrawable(mIcons[position]);
return convertView;
}
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null){
convertView = mInflator.inflate(R.layout.navigation_list_dropdown_item, parent, false);
holder = new ViewHolder();
holder.icon = (ImageView)convertView.findViewById(R.id.icon);
holder.title = (TextView)convertView.findViewById(R.id.title);
convertView.setTag(holder);
}else{
holder = (ViewHolder)convertView.getTag();
}
holder.title.setText(mTitles[position]);
holder.icon.setImageDrawable(mIcons[position]);
return convertView;
}
private class ViewHolder{
public ImageView icon;
public TextView title;
}
}
onCreate method of the activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Context context = getSupportActionBar().getThemedContext();
TypedArray ta = getResources().obtainTypedArray(R.array.leagues);
Drawable[] logos = new Drawable[ta.length()];
for(int i = 0; i < logos.length; i++){
logos[i] = ta.getDrawable(i);
}
NavigationListAdapter adapter = new NavigationListAdapter(context, logos,
getResources().getStringArray(R.array.league_names));
getSupportActionBar().setDisplayShowTitleEnabled(false);
getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
getSupportActionBar().setListNavigationCallbacks(adapter, null);
}
An illustration of the problem:
Maybe changing the width of your textview in navigation_list_dropdown_item.xml to wrap_content take effect (if changing width of LinearLayout does not work). You can see this to: http://dandar3.blogspot.com.es/2013/03/actionbarsherlock-custom-list-navigation.html .
I'm trying to get my spinneradapter working. I get no error's but
the spinner remains empty. I have read multiple tutorials but they aren't seem to work
very well. I'm trying to turn every row in a specifik color, that's why I need the adapter.
This is my code:
public class spinnerAdapter extends ArrayAdapter<String> implements
SpinnerAdapter {
Context context;
ArrayList<String> dateArray;
public spinnerAdapter(Context context, ArrayList<String>dateArray) {
super(context, R.layout.ruilen2_spinner);
this.context = context;
this.dateArray = dateArray;
}
static class ViewHolder {
public TextView textView;
public TextView textView2;
}
#Override
public View getDropDownView(int position, View view, ViewGroup parent) {
View rowView = view;
final ViewHolder holder;
if (rowView == null) {
LayoutInflater vi = (LayoutInflater) getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
rowView = vi.inflate(R.layout.ruilen2_spinner, null);
holder = new ViewHolder();
holder.textView = (TextView)rowView.findViewById(R.id.spinnerdate);
//holder.textView2 = (TextView)rowView.findViewById(R.id.spinnerworkplace);
rowView.setTag(holder);
}
else{
holder = (ViewHolder) rowView.getTag();
}
holder.textView.setText(dateArray.get(position));
return super.getDropDownView(
position, rowView, parent);
}
}
Here's the code snippet where I call the class:
s.setAdapter(new spinnerAdapter(getParent(),namen));
And last but not least the XML:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:background="#color/white"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="#+id/spinnerdate" android:textColor="#color/black"></TextView>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="#+id/spinnerworkplace" android:textColor="#color/black"></TextView>
</LinearLayout>
If it is displaying but is empty then you might not be creating your dateArray properly. Did you check to make sure namen in s.setAdapter(new spinnerAdapter(getParent(),namen)); has anything in it?