Can't find ViewByID in Custom Adapter - android

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

Related

How to Hide or Kill The White Space Below The Spinner Drop-Down List

I have successfully implemented Spinners in my project using the Spinner class which exists in this link:
How to make an Android Spinner with initial text "Select One"
Also, I customized the layout of each item and named it as spinner_entries_style.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="match_parent"
android:background="#ffffff"
android:orientation="vertical" >
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="2dp"
android:background="#640c1c"
android:maxEms="10"
android:padding="10dp"
android:singleLine="false"
android:textColor="#d7a801"
android:textSize="18sp" />
</LinearLayout>
Also, These are the Adapter classes I used in my code..
class LoanTypeAdapter extends ArrayAdapter<String> {
Context context;
String[] items;
public LoanTypeAdapter(Context context, String[] items) {
super(context, R.layout.spinner_entries_style, R.id.textView, items);
this.context = context;
this.items = items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
ViewHolder holder = null;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(android.R.layout.simple_spinner_item,
parent, false);
holder = new ViewHolder(view);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.textView.setText(items[position]);
holder.textView.setTextColor(Color.parseColor("#d7a801"));
holder.textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
holder.textView.setSingleLine(true);
return holder.textView;
// ------------------------------------------
}
class ViewHolder {
final TextView textView;
ViewHolder(View view) {
textView = (TextView) view;
}
}
}
And this..
class LoanProgramAdapter extends ArrayAdapter<String> {
Context context;
String[] items;
public LoanProgramAdapter(Context context, String[] items) {
super(context, R.layout.spinner_entries_style, R.id.textView, items);
this.context = context;
this.items = items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
ViewHolder holder = null;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(android.R.layout.simple_spinner_item,
parent, false);
holder = new ViewHolder(view);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.textView.setText(items[position]);
holder.textView.setTextColor(Color.parseColor("#d7a801"));
holder.textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
holder.textView.setSingleLine(true);
return holder.textView;
}
class ViewHolder {
final TextView textView;
ViewHolder(View view) {
textView = (TextView) view;
}
}
}
But, there is something strange I encountered after building the spinners. When running the app in Android versions (4.2 or less), there is a white space below the dropdown list.
Here are the screenshots of what happens..
http://www.mediafire.com/view/cqj51t8e3aju18m/01.png
http://www.mediafire.com/view/ure788yetrt00v3/02.png
That is not just on the emulator, but also in the real devices having Android 4.2 or less. Also, this white space seems a bit bigger in some devices.
Is there any idea to hide or kill these white area? Any solution for this problem?
I found the solution of this problem after reading this post.
How to wrap lengthy text in a spinner
In my layout called spinner_entries_style.xml, I should specify the height of text view like that:
android:layout_height="?android:attr/listPreferredItemHeight"
And it will be like that:
<?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:background="#ffffff"
android:orientation="vertical" >
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:layout_marginBottom="2dp"
android:background="#640c1c"
android:maxEms="10"
android:padding="10dp"
android:singleLine="false"
android:textColor="#d7a801"
android:textSize="18sp" />
</LinearLayout>
That solved my problem successfully..
Remove this line from spinner_entries_style.xml.
android:layout_marginBottom="2dp"

Can't find TextView in recursive custom Listview adapter

I created this class called GeoArea, which is suppose to store "Geographical Area" that have children Geographical Areas, this is fairly strait foward:
public class GeoArea {
public String id;
public String name;
public List<GeoArea> subGeoAreas;
public GeoArea parentGeoArea;
public GeoArea(String id) {
this.id = id;
name = id;
subGeoAreas = new LinkedList<GeoArea>();
}
#Override
public String toString() {
return name;
}
}
I have created the following Layout to render it on Android, the idea here is to for each GeoArea to recursively render it self and then it's children GeoArea in a listView:
//layout_geo_area.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/txtGeoAreaName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:gravity="left"
android:text="Geo Area Name"
android:textAppearance="?android:attr/textAppearanceLarge" />
<ListView
android:id="#+id/listViewChildGeoAreas"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/txtGeoAreaName"
android:gravity="left" >
</ListView>
</RelativeLayout>
This is my adapter I created for GeoArea to be displayed in a listView:
public class AdapterGeoArea extends ArrayAdapter<GeoArea>{
private ArrayList<GeoArea> _myGeoArea;
private Context _myContext;
LayoutInflater _inflater;
public AdapterGeoArea(Context context, ArrayList<GeoArea> myGeoArea) {
super(context, 0, myGeoArea);
_myGeoArea = myGeoArea;
_inflater = LayoutInflater.from(context);
_myContext = context;
}
public int getCount() {
return _myGeoArea.size();
}
public View getView(int position, View convertView, ViewGroup parent) {
GeoAreaLayoutHolder holder;
if (convertView == null) {
convertView = _inflater.inflate(R.layout.layout_geo_area,parent,false);
holder = new GeoAreaLayoutHolder();
holder.txtGeoAreaName = (TextView)convertView.findViewById(R.id.txtGeoAreaName);
holder.txtGeoAreaName.setTag(convertView);
holder.listViewChildGeoAreas = (ListView)convertView.findViewById(R.id.listViewChildGeoAreas);
holder.listViewChildGeoAreas.setTag(convertView);
} else {
holder = (GeoAreaLayoutHolder) convertView.getTag();
}
GeoArea curGeoArea = _myGeoArea.get(position);
holder.txtGeoAreaName.setText(curGeoArea.name);
if(curGeoArea.subGeoAreas.size()>0){
ArrayList<GeoArea> testList = new ArrayList<GeoArea>();
AdapterGeoArea adapter = new AdapterGeoArea(_myContext, testList);
for(GeoArea childGeoArea:curGeoArea.subGeoAreas){
testList.add(childGeoArea);
}
holder.listViewChildGeoAreas.setAdapter(adapter);
}
return convertView;
}
static class GeoAreaLayoutHolder {
public TextView txtGeoAreaName;
public ListView listViewChildGeoAreas;
}
}
And here is my Activity that I am using to set it all up:
public class ActivityGeoAreas extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_geo_area);
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.listViewChildGeoAreas);
lv.setAdapter(adapter);
}
}
When I try to run it, I get the error nullPointerException on the line:
holder.txtGeoAreaName.setText(curGeoArea.name);
What am I doing wrong?
You may want to check ExpandableListView may suit your needs better
http://developer.android.com/reference/android/widget/ExpandableListView.html
An example # http://www.androidhive.info/2013/07/android-expandable-list-view-tutorial/
Continuing from my previous answer to your question ( i though that solved your problem)
To display just name in your listview
list_row.xml // this is the layout with textview to be inflated in getView.
Each row will have textview
<?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>
layout_geo_area.xml // with only listview no textview
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ListView
android:id="#+id/listViewChildGeoAreas"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:gravity="left" >
</ListView>
</RelativeLayout>
Now your adapter class
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.list_row,parent,false);
// inflate list_row.xml with textview
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;
}
You have a custom adapter.
public class AdapterGeoArea extends ArrayAdapter<GeoArea>{
Now you set the adapter to listview like below
AdapterGeoArea adapter = new AdapterGeoArea(this, testList);
ListView lv = (ListView) findViewById(R.id.listViewChildGeoAreas);
lv.setAdapter(adapter);
So why do you need the below. remove these
if(curGeoArea.subGeoAreas.size()>0){
ArrayList<GeoArea> testList = new ArrayList<GeoArea>();
AdapterGeoArea adapter = new AdapterGeoArea(_myContext, testList);
for(GeoArea childGeoArea:curGeoArea.subGeoAreas){
testList.add(childGeoArea);
}
holder.listViewChildGeoAreas.setAdapter(adapter);

CustomListView onItemClickListener not working while using HorizontalScrollView, Infinitely called getView() method

I am using the following code.
Adapter.java class
public class Adapter extends ArrayAdapter<String> {
private java.util.List<String> List;
private Context context;
public Adapter(List<String> list, Context ctx) {
super(ctx, R.layout.row_item, list);
this.List = list;
this.context = ctx;
}
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
NameHolder holder = new NameHolder();
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.row_item, null);
TextView tv = (TextView)v.findViewById(R.id.textView1);
LinearLayout ll = (LinearLayout) v.findViewById(R.id.myLayout);
holder.topic_name = tv;
holder.myLayout = ll;
v.setTag(holder);
}
else
holder = (NameHolder) v.getTag();
String topic = List.get(position);
holder.topic_name.setText(topic);
ImageView imgUsers = new ImageView(context);
imgUsers.setImageResource(R.drawable.ic_launcher);
holder.myLayout.addView(imgUsers);
return v;
}
private static class NameHolder {
public TextView topic_name;
public LinearLayout myLayout;
}
}
MainActivity.java class :
public class MainActivity extends Activity {
ListView lv;
ArrayList<String> list;
Adapter myAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView)findViewById(R.id.listView1);
list = new ArrayList<String>();
for(int i=0; i<10;i++){
list.add("Name"+i);
}
myAdapter = new Adapter(list, MainActivity.this);
lv.setAdapter(myAdapter);
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this,"lets see"+list.get(arg2), Toast.LENGTH_SHORT).show();
}
});
}
}
activity_main.xml :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
row_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="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
<HorizontalScrollView
android:id="#+id/horizontalScrollView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:orientation="horizontal"
android:id="#+id/myLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
></LinearLayout>
</HorizontalScrollView>
</LinearLayout>
Now, the expected output is a single image in every listItem, which tend to go to infinite.
And the onItemClickListener is not working as well.
Also, onItemClickListener works if we don't add HorizontalScrollView.
Writing onClickListener() in Adapter itself helps little as it works unpredictably.
Also, on adding a print statement in getView() and observing in Logcat, I find it difficult to understand the pattern in which getView() is called.
These are the problems I face. I require a working code of the things I wish to apply. Thanks in advance.
// Replace this code
public View getView(int position, View convertView, ViewGroup parent) {
NameHolder holder;
if (convertView == null) {
holder = new NameHolder();
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.row_item, null);
holder.topic_name = (TextView)convertView.findViewById(R.id.textView1);
holder.myLayout = (LinearLayout) convertView.findViewById(R.id.myLayout);
convertView.setTag(holder);
}
else
holder = (NameHolder) convertView.getTag();
String topic = List.get(position);
holder.topic_name.setText(topic);
ImageView imgUsers = new ImageView(context);
imgUsers.setImageResource(R.drawable.ic_launcher);
holder.myLayout.removeAllViews();
holder.myLayout.addView(imgUsers);
convertView.setTag(holder);
return convertView;
}
Looks like you are adding an ImageView every single time here
ImageView imgUsers = new ImageView(context);
imgUsers.setImageResource(R.drawable.ic_launcher);
holder.myLayout.addView(imgUsers);
Why don't you include the ImageView as part of your list item layout?

findViewByID returning null on BaseAdapter

I started using fragments to develop a new app, one of the fragments is a ListFragment,
when I use the adapter I made to show the list's rows I get some null from some findViewById that I use on the getView() method.
The structure is:
activity_main.xml
<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"
tools:context=".MainActivity">
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/fragment_container">
</FrameLayout>
</RelativeLayout>
frag_detail.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#android:id/list"
android:layout_gravity="center"/>
</LinearLayout>
detail_list_item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/detailItemLayout" >
<ImageButton
android:layout_width="64dp"
android:layout_height="64dp"
android:id="#+id/imgIcon"
android:layout_below="#+id/txtTitle"
android:layout_centerHorizontal="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="txtTitle"
android:id="#+id/txtTitle"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="label1"
android:id="#+id/label1"
android:layout_below="#+id/imgIcon"
android:layout_alignParentLeft="true"/>
</RelativeLayout>
DetailFragment class
public class DetailFragment extends ListFragment {
private Context context;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.frag_detail,container,false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
MonsterDataSource ds = new MonsterDataSource(context);
List<Monster> lsMonster = ds.getAllMonsters();
//ListView lsView = (ListView)this.getActivity().findViewById(R.id.lsDetail);
MonsterListAdapter adapter = new MonsterListAdapter(context,lsMonster);
//lsView.setAdapter(adapter);
setListAdapter(adapter);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
context = activity.getApplicationContext();
}
}
And the MonsterListAdapter class
public class MonsterListAdapter extends BaseAdapter {
static class ViewHolder {
private TextView txtTitle;
private ImageView imgIcon;
private TextView txtHealth;
}
private Context context;
private LayoutInflater inflater;
private List<Monster> data;
private ViewHolder holder;
public MonsterListAdapter(Context c, List<Monster> data){
context = c;
this.data = data;
inflater = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
/*Basic BaseAdapter Methods*/
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
if (view == null) {
view = inflater.inflate(R.layout.menu_list_item, null);
holder = new ViewHolder();
/*Those Guys get null*/
RelativeLayout layout = (RelativeLayout)view.findViewById(R.id.detailItemLayout);
holder.txtTitle = (TextView) view.findViewById(R.id.txtTitle);
holder.imgIcon = (ImageView) view.findViewById(R.id.imgIcon);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
Monster monster = data.get(i);
holder.txtTitle.setText(monster.name);
holder.imgIcon.setImageResource(monster.imgResID);
holder.txtHealth.setText(monster.health);
return view;
}
}
In case anyone asking, I'm trying to retrieve the relative layout to add some controls dynamically after.
Thanks
You posted the XML for detail_list_item.xml but in your code you inflate menu_list_item.xml.
detail_list_item.xml contains all of the IDs you are trying to find so it appears you have accidentally inflated the wrong View in getView
Additionally, you should remove your ViewHolder as a member variable and place it as a local variable in the getView method. You are reusing that variable for multiple views at the same time which means you have the potential for modifying the wrong views at different positions (data going to the wrong positions, etc).
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder holder;
...
...//all of your other code here
}
Try without affecting "view"
RelativeLayout layout = (RelativeLayout)findViewById(R.id.detailItemLayout);
holder.txtTitle = (TextView) findViewById(R.id.txtTitle);
holder.imgIcon = (ImageView) findViewById(R.id.imgIcon);
Edit This works for me... My texviews nbCommentaires and Comment give NullPointerException if i inflate View to them... I thought you get the same issue...
#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.comment_row, null);
}
v.setTag(position);
Commentaires o = Global_reco.CommRecos.get(position);
if (o != null) {
TextView nom = (TextView) v.findViewById(R.id.nom_com);
TextView com = (TextView) v.findViewById(R.id.com);
ImageView photo = (ImageView) v.findViewById(R.id.profile_com);
TextView nbCommentaires = (TextView) findViewById(R.id.nb_commentaires);
TextView Comment = (TextView)findViewById(R.id.nbre_comment);
photo.setTag(position);

ActionBarSherlock list navigation with icon and title

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 .

Categories

Resources