Issue trying to change ImageView in List Activity - android

I am having problems when I try to alter the image in a list view.
Below is the layout XML for the row in the list:
<?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="?android:attr/listPreferredItemHeight"
android:orientation="horizontal"
android:gravity="left">
<ImageView
android:id="#+id/flagIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="0.1"
android:src="#drawable/orange_flag"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="vertical" >
<TextView
android:id="#+id/location_row_item_main_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/location_row_item_secondary_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textAppearance="?android:attr/textAppearanceSmall"/>
</LinearLayout>
Runs ok and shows the drawable stated (i.e. orange_flag), but this doesn't change when I try and alter it in the following code:
private class MyListAdapter extends ResourceCursorAdapter {
// In your ListActivity class, create a new inner class that extends ResourceCursorAdapter.
//This inner class is the custom CursorAdapter we will use to manage how data is bound to a list item:
public MyListAdapter(Context context, Cursor cursor) {
super(context, R.layout.row_location, cursor);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
TextView title = (TextView) view.findViewById(R.id.location_row_item_main_text);
title.setText(cursor.getString(
cursor.getColumnIndex(RMDbAdapter.RACKING_SYSTEM)));
ImageView flagIcon = (ImageView) view.findViewById(R.id.flagIcon);
String risk = cursor.getString(cursor.getColumnIndex(RMDbAdapter.RISK));
if (risk == "Red Risk"){
flagIcon.setImageResource(R.drawable.red_flag);
}
else if (risk == "Green Risk"){
flagIcon.setImageResource(R.drawable.green_flag);
}
else if (risk =="No Risk"){
flagIcon.setImageResource(R.drawable.note);
}
Any ideas?!

Always use equals() or equalsIgnoreCase() when comparing String data type for the contents.
For strings in java:
== compares whether strings are same Object or not.
equals() compares whether strings have same sequence of characters or not.

Try adding flagIcon.invalidate() after setting the resource.

Instead of trying
flagIcon.setImageResource(R.drawable.red_flag);
You can try this :
flagIcon.setBackgroundResource(R.drawable.red_flag);

Related

Setting instance variable in a Android View context class

I am trying to create a dynamic android layout with multiple views. The number of views are dependent on the items in a list.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/layout_category"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_marginBottom="5px"
android:layout_marginTop="5px"
android:orientation="vertical"
android:padding="5dp" tools:context=".CategoryActivity">
<ImageView
android:id="#+id/img_category"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:foregroundGravity="center"
android:src="#android:drawable/ic_menu_view"/>
<TextView
android:id="#+id/text_category"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Category"
android:textColor="#000000"
android:layout_alignParentStart="true"/></LinearLayout>
I inflate this view and then add to the mainlayout
View view = getLayoutInflater().inflate(R.layout.activity_category_view, null);
mainLayout.addView(view)
The context class for the view CategoryActivity has a instance variable categoryId
I need to set the value this categoryId and refer it later i.e. during onClick action and then take appropriate action
in the CategoryActivity class i have duly mentioned
setContentView(R.layout.activity_category_view);
I have tried various ways but still not able to resolve and am stuck for good !
In case of dynamic views, you must use getTag and setTag methods to store and retrieve data into/from the views. See the below code based on your question:
View view = getLayoutInflater().inflate(R.layout.activity_category_view, null);
view.setTag(categoryId);
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int cat_id=(Integer)view.getTag();
// do whatever you want to do further with it
}
});
mainLayout.addView(view);
I hope this will help you.
You can do something like
android:tag="MyInstanceVariable"
<ImageView
android:id="#+id/img_category"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:tag="MyInstanceVariable"
android:foregroundGravity="center"
android:src="#android:drawable/ic_menu_view"/>
you can add it dynamically
iv.setTag("MyInstanceVariable");
iv.setTag(R.String.Tag,"MyInstanceVariable"); //For multiple Tag
and you can access in java file like
String tag = (String) iv.getTag();
String tag = (String) iv.getTag(R.String.Tag);

retrieve data from ArrayList<Object> to Listview Android

i have a problem with my ListView , I cannot get the data from an arraylist to listview . Data from arraylist was loaded successful from the data and when I put it in the ArrayAdapter the app always say ArrayAdapter requires the resource ID to be a TextView
Here my code
EventList.java
public class EventList extends Activity {
ListView listView;
DBHelper db;
List<String> event_name;
private TextView e_name,e_location,e_date,e_time,e_or;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_event_list);
db = new DBHelper(this);
listView = (ListView) findViewById(R.id.eventlist);
db.open();
ArrayList<Event> elist= db.getEventlist();
db.close();
e_name=(TextView) findViewById(R.id.e_name);
e_date=(TextView) findViewById(R.id.e_date);
e_location =(TextView) findViewById(R.id.e_location);
e_time =(TextView) findViewById(R.id.e_time);
e_or =(TextView) findViewById(R.id.e_or);
// for(int i=0;i<elist.size();i++)
// {
// e_name.setText(elist.get(i).getEventName());
// e_date.setText(elist.get(i).getDate());
// e_location.setText(elist.get(i).getLocation());
// e_time.setText(elist.get(i).getTime());
// e_or.setText(elist.get(i).getOrganizer());
// }
ArrayAdapter<Event> arrayAdapter = new ArrayAdapter<Event>(
this,
R.layout.each_event,elist);
listView.setAdapter(arrayAdapter);
}
}
activity_event_list.xml
<?xml version="1.0" encoding="utf-8"?>
<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="com.greenwich.thaotb.eventmanagement.EventList">
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Event List"
android:id="#+id/textView2"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Event"
android:id="#+id/textView3"
android:layout_marginTop="26dp"
android:layout_below="#+id/textView2"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:text="Event"
android:ems="10"
android:id="#+id/event_name"
android:layout_alignBottom="#+id/textView3"
android:layout_toRightOf="#+id/textView3"
android:layout_toEndOf="#+id/textView3"
android:layout_marginLeft="33dp"
android:layout_marginStart="33dp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Search"
android:id="#+id/bnt_search"
android:layout_below="#+id/event_name"
android:layout_alignRight="#+id/event_name"
android:layout_alignEnd="#+id/event_name" />
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/eventlist"
android:layout_below="#+id/bnt_search"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:choiceMode="singleChoice" />
</RelativeLayout>
each_event.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">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:id="#+id/e_name" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:id="#+id/e_location" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:id="#+id/e_date" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:id="#+id/e_time" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:id="#+id/e_or" />
</LinearLayout>
Take a look at the documentation for the the constructor for ArrayAdapter that you're using. It says the resource ID must be a layout with a TextView. It turns out, in this case, that the layout must contain ONLY a single TextView. If you have a different case, use a different constructor.
ArrayAdapter populates a ListView by taking the toString() value of the object in its array, then putting that into the TextView identified by the layout you passed.
Two problems
You can't use the ArrayAdapter constructor for displaying any complex data objects. It will just toString all the objects.
Calling findViewById(R.id.e_name) (and the others) from within the Activity will return null because #+id/e_name isn't from the activity_event_list.xml file.
To solve these, you'll need to implement a custom ArrayAdapter for your Event objects.
Something like so
public class EventAdapter extends ArrayAdapter<Event> {
public EventAdapter(Context context, ArrayList<Event> events) {
super(context, 0, events);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
Event event = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.each_event, parent, false);
}
TextView eName = (TextView) convertView.findViewById(R.id.e_name);
// get other views ...
eName.setText(event.getEventName());
// set other views...
return convertView;
}
}
Then in the Activity, you can do
ArrayList<Event> elist= db.getEventlist();
EventAdapter adapter = new EventAdapter(this, elist);
listView.setAdapter(adapter);
I have read your code, and I think it's worth first checking how ListViews and and Adapters work together. Here's a great article I think you should take a look at.
Solution
You can achieve what you want by
Creating a custom class that represents an event, it should be something like this
class Event{
private String mName;
private String mLocation;
private String mDate;
//you get the idea ...
public Event (String name, String location, String date){
mName = name;
mLocation = location;
mDate = date;
}
//some getters
public String getName (){
return mName;
}
public String getLocation (){
return mLocation;
}
public String getDate (){
return mDate;
}
//you can add other logic here depending on what you want your event to do
}
Creating you collection of Events, a List<Event> will do
Creating your custom EventAdapter, I would recommend to extend the BaseAdapter class (any other Adapter class would do)
A tutorial might help you more
Here is a great step by step tutorial showing how to implement what I have mentioned above.

Extending RelativeLayout by inflating from xml?

I want to create a class named TabView which extends RelativeLayout and it is inflated from xml that contains RelativeLayout. The thing is that it doesn't seem to work as I expected. Did I do something wrong in the constructor? I know layoutInflater.inflate returns View object but what do I have to make it equal to? Any advice is apprecited!
private class TabView extends RelativeLayout {
private int mIndex;
public TabView(Context context) {
super(context, null, R.attr.vpiTabPageIndicatorStyle);
LayoutInflater layoutInflater = LayoutInflater.from(context);
layoutInflater.inflate(R.layout.tabview_title_subtitle, null);
}
public int getIndex() {
return mIndex;
}
public void setTitle() {
TextView title = (TextView)findViewById(R.id.title);
title.setText("Followers");
}
public void setSubitle() {
TextView subtitle = (TextView)findViewById(R.id.subtitle);
subtitle.setText("435");
}
}
The following is tabview_title_subtitle.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/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:text="Title"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="#+id/title"
android:text="Subtitle"
android:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>
First, your layout should look like this:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:text="Title"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="#+id/title"
android:text="Subtitle"
android:textAppearance="?android:attr/textAppearanceMedium" />
</merge>
In other way you'll end up with RelativeLayout that contains another RelativeLayout
Second. Inflate it like this:
layoutInflater.inflate(R.layout.tabview_title_subtitle, this);
You can see the following blog for creating and using custom views in android.
And probably using
inflater.inflate(R.layout.view_color_options, this, true);
instead of
layoutInflater.inflate(R.layout.tabview_title_subtitle, null);
is what you need to do.
Use:
layoutInflater.inflate(R.layout.tabview_title_subtitle, this);
to actually add the inflated view to TabView(right now you just inflate it and immediately discard it). Also if you want to use your custom view in a xml layout then also implement the constructor that takes a Context and an AttributeSet.

Make a TextView inside a ListView use the default ListView row style

My app generates 2 different lists, one uses the default ListView style as the ListView rows contain no TextView inside of them. The other list uses a custom CursorAdapter and has a TextView inside each row. All I want to do is make it so that the margins and text size are exactly the same for both lists.
My first list is using a standard ListView with no TextView inside each row, here is what it looks like:
Here is the code to generate it:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.records);
DatabaseHandler db = new DatabaseHandler(this);
ArrayList<String> records = db.getRecords(this);
this.setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, records));
}
Here is the xml file for it:
<?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" >
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
My second list is using a ListView with a TextView inside each row that is generated via a custom `CursorAdapter, here is what it looks like:
Here is the code to generate it:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.achievements);
DatabaseHandler db = new DatabaseHandler(this);
Cursor cursor = db.getAchievements(this);
AchievementAdapter cursorAdapter = new AchievementAdapter(this, cursor);
this.setListAdapter(cursorAdapter);
}
private class AchievementAdapter extends CursorAdapter {
public AchievementAdapter(Context context, Cursor c) {
super(context, c);
}
#Override
public void bindView(View v, Context context, Cursor cursor) {
TextView tv = (TextView) v.findViewById(R.id.achView1);
if(cursor.getString(cursor.getColumnIndex("completed")).equals("yes")) {
tv.setText(cursor.getString(cursor.getColumnIndex("name"))+" (completed)");
tv.setTextColor(Color.GREEN);
}
else {
tv.setText(cursor.getString(cursor.getColumnIndex("name")));
}
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(R.layout.achievements_item, parent, false);
return v;
}
}
Here is the achievements xml file for it:
<?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" >
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/android:empty"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text=""/>
</LinearLayout>
Here is the achievements_item xml for it:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:id="#+id/achView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="" />
</LinearLayout>
Basically I just want these 2 lists to look exactly the same. Is there a way to do it so that the TextView inherits the default ListView row style? Or am I going to have to play with the margins and everything myself?
Just copy the attributes of the TextView from the default ListView layout android.R.layout.simple_list_item_1 and use them on your own row layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:id="#+id/achView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:gravity="center_vertical"
android:paddingLeft="6dip"
android:minHeight="?android:attr/listPreferredItemHeight" />
</LinearLayout>
Also, if all you want for the customized ListView row layout is a TextView, you could remove the parent LinearLayout so you don't have an extra View in the layout
In achievements_item.xml add some padding to the top and bottom of the TextView
<TextView
android:id="#+id/achView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:text="" />

android list inside layout

i am working on an Android app that needs showing a list[table], inside the layout[view]
I come from iPhone dev objC land, and i have an app that shows a table[list] inside the view[layout]
So how to show a list inside my layout, and place it to specified location [center],
ps. I havent found a list in the graphical layout editor of the xml, where is the list[table]?
2. I have done some tests with list views, but is a view, that replace the xml view, i want it inside my xml,,
thanks a lot!
Yes, of course, you can do that
1) you need to have listholder.xml here, you can scratch anything in you layout view, either imageview, textview..etc. just don't forget to add ListView inside it. for example:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/head_logo_bg">
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/background_label">
<TextView
android:id="#+id/city_txt"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_gravity="center"
android:text="Sydney"
android:textStyle="bold"
android:textSize="17sp"/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="40sp">
<ListView
android:id="#android:id/list"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_centerVertical="true"
android:scrollingCache="false"/>
</LinearLayout>
2) For custom your own list item, you have to create listitem.xml i.e.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/listitemone"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10sp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:orientation="vertical">
<ImageView android:id="#+id/user_image"
android:layout_width="80px" android:layout_height="80px"
android:layout_alignParentLeft="true"
android:layout_marginRight="5px"
android:src="#drawable/icon"
/>
</LinearLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="5sp"
android:orientation="vertical">
<TextView
android:id="#+id/date_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/date"
android:textStyle="bold"
android:textSize="16sp" />
<TextView
android:id="#+id/date_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignBaseline="#id/date_label"
android:layout_marginRight="20sp"
android:textColor="#FFF"
android:text="MM/dd/YYYY"
android:textStyle="bold"
android:textSize="16sp" />
</RelativeLayout>
</LinerLayout>
3) create customAdapter in your activity, it would look like this;
public class MyListActivity extends ListActivity {
private ArrayList<Yourdata> yourdata = new ArrayList<Youdata>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listholder);
// yourdata might be array, arraylist etc.
MyCustomAdapter listadapter = new MyCustomAdapter(this, R.layout.listitem, yourdata);
setListAdapter(listadapter);
}
private class MyCustomAdapter extends ArrayAdapter<Yourdata>{
//this case, i use Yourdata as type
private ArrayList<Yourdata> items;
public PreviousAdapter(Context context, int textViewResourceId,
ArrayList<Yourdata> items) {
super(context, textViewResourceId, items);
this.items = items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if(v == null) {
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.listitem, null);
}
Yourdata yt = items.get(position);
if(yt != null){
// Don't forget to use v.findView...., otherwise, it might force close when run app.
TextView dateStr = (TextView)v.findViewById(R.id.date_value);
dateStr.setText(yt.getDate());
}
return v;
}
}
}
P.S. the above code might not exactly right... just give you an idea :)
Here is a source about custom list (you might have seen it) hope it useful
http://www.vogella.de/articles/AndroidListView/article.html
I have try these example it's very nice.
you can get the example from
http://www.codeproject.com/Articles/507651/Customized-Android-ListView-with-Image-and-Text?msg=4567162#xx4567162xx

Categories

Resources