I'm using a Gridview to show a list of skills. The code runs fine, even populates exact number of items according to my array. However, the TextView that should display the item names is blank.
This is the code for my gridview adapter
SkillsAdapter.java
public class SkillsAdapter extends BaseAdapter {
private Context context;
private final String[] skillValues;
public SkillsAdapter(Context context, String[] skillValues) {
this.context = context;
this.skillValues = skillValues;
}
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridView;
if (convertView == null) {
// get layout from mobile.xml
gridView = inflater.inflate(R.layout.skills_single_item, null);
// set value into textview
textView = (TextView) gridView.findViewById(R.id.single_label);
textView.setText(skillValues[position]);
} else {
gridView = (View) convertView;
}
return gridView;
}
#Override
public int getCount() {
return skillValues.length;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
}
This is the code for my layout file skills_single_item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dp"
android:background="#drawable/rounded_corners">
<TextView
android:id="#+id/single_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_gravity="center"/>
</RelativeLayout>
The array is not null. The error occurs somewhere around here
// set value into textview
textView = (TextView) gridView.findViewById(R.id.single_label);
textView.setText(skillValues[position]);
Change your layout Item XML with this your I used your Adapter class its work fine at my side
it may help you
<?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="wrap_content"
android:background="#FFFFFF"
android:orientation="horizontal"
android:padding="5dp">
<TextView
android:id="#+id/single_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="8dp"
android:textColor="#000000" />
</RelativeLayout>
Set test in your text view out of if condition like:
if (convertView == null) {
// get layout from mobile.xml
gridView = inflater.inflate(R.layout.skills_single_item, null);
// set value into textview
textView = (TextView) gridView.findViewById(R.id.single_label);
} else {
gridView = (View) convertView;
}
textView.setText(skillValues[position]);
Move following line out of if-else blocks
textView.setText(skillValues[position]);
Like
if (convertView == null) {
// get layout from mobile.xml
gridView = inflater.inflate(R.layout.skills_single_item, null);
textView = (TextView) gridView.findViewById(R.id.single_label);
} else {
gridView = (View) convertView;
}
// set value into textview
textView.setText(skillValues[position]);
I recommend you to read android ViewHolder pattern.
Related
I am trying to inflate listView with two different layouts using ArrayAdapter.
I want to show some user posts. If it contains a picture use one layout if it does not use second.
I am doing so far
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Post post = getItem(position);
boolean noImg = post.mImgUrl1 == null && post.mImgUrl2 == null;
if (convertView == null){
if (noImg)
convertView = LayoutInflater.from(getContext()).inflate(R.layout.post_item_no_img, parent ,false);
else
convertView = LayoutInflater.from(getContext()).inflate(R.layout.post_item, parent, false);
}
if (noImg == false) {
mTitle = (TextView) convertView.findViewById(R.id.tv_titlePost);
mText = (TextView) convertView.findViewById(R.id.tv_textPost);
mImage = (ImageView) convertView.findViewById(R.id.iv_postimg);
}
else {
mNoImgTitle = (TextView) convertView.findViewById(R.id.tv_noImgTitle);
mNoImgText = (TextView) convertView.findViewById(R.id.tv_noImgText);
}
if (noImg) {
mNoImgTitle.setText(post.mTitle);
mNoImgText.setText(post.mText);
if (post.mImgUrl1 != null)
Glide.with(mImage.getContext()).load(post.mImgUrl1).into(mImage);
else Glide.with(mImage.getContext()).load(post.mImgUrl2).into(mImage);
}
else {
mNoImgTitle.setText(post.mTitle);
mNoImgText.setText(post.mText);
}
return convertView;
}
But i realized that textviews from second layout cannot be found by findViewById function. And it always returns a null-pointer.
What are my solutions ? Should i make only one Layout and somehow trick it using visibility ? Or there is a way ?
There are a few different scenarios that you will see when getView() is called:
convertView is null: In this case just create the layout that you need depending upon noImg;
convertView is defined but is of the wrong type. In this case, you will need to discard the old view and create the one you need;
convertView is defined but is of the correct type, in which case, we do nothing with it.
The following code is one approach to making sure that you are always working with the right layout and can find the ids that you expect. This code uses a tag in the inflated layout to identify the layout type that can be checked.
if (convertView == null || noImg != (boolean) convertView.getTag()) {
// Either there is no view defined or it is the wrong type. Create
// the type we need.
if (noImg) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.post_item_no_img, parent, false);
} else {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.post_item, parent, false);
}
convertView.setTag(noImg);
}
With BaseAdapter you can create more complex layouts. Try using it.
Here is the example of use for your situation:
Activity:
public class TestActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String[] data={"false","false","true","true","false","true"};
ListView listViewTest=(ListView)findViewById(R.id.listViewTest);
TestAdapter testAdapter=new TestAdapter(data);
listViewTest.setAdapter(testAdapter);
}
}
Adapter:
public class TestAdapter extends BaseAdapter {
private String[] data;
TestAdapter(String data[]) {
this.data = data;
}
#Override
public int getCount() {
return data.length;
}
#Override
public Object getItem(int i) {
return data[i];
}
#Override
public long getItemId(int i) {
return i;
}
public View getView(int position, View convertView, ViewGroup parent) {
if (data[position].equals("false")) {
convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_no_img, parent, false);
} else if (data[position].equals("true")) {
convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_img, parent, false);
}
return convertView;
}
}
Layouts:
activity_main
<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/listViewTest"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
list_item_no_img
<?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:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/textViewTest"
android:gravity="center"
android:layout_centerInParent="true"
android:textSize="32sp"
android:text="Test"/>
</RelativeLayout>
list_item_img
<?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:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/textViewTest"
android:gravity="center"
android:layout_centerInParent="true"
android:textSize="32sp"
android:text="Test"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#mipmap/ic_launcher"
android:layout_marginStart="5dp"
android:layout_marginLeft="5dp"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/textViewTest"
android:layout_toEndOf="#+id/textViewTest" />
</RelativeLayout>
Result:
Hellow i've implemented ListView inside the CardView but now what problem i got is, the CardView is not Expanding on Adding list item. Can anybody help me,how to slove the issue? I have gone through different posts on stackoverflow but cannot find the solution :( My code is below
//this is my Listview adapter Class
public class EmploymentHistoryAdapter extends BaseAdapter {
public ArrayList<EmploymentHistory> mEmploymentHistories;
private Context context;
public EmploymentHistoryAdapter(ArrayList<EmploymentHistory> mEmploymentHistories, Context context) {
this.mEmploymentHistories = mEmploymentHistories;
this.context = context;
}
#Override
public int getCount() {
return mEmploymentHistories.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = null;
EmploymentHistory empHistory = mEmploymentHistories.get(position);
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.list_employee_history_row, parent, false);
} else {
v = convertView;
}
TextView hospital = (TextView) v.findViewById(R.id.hospital);
TextView department = (TextView) v.findViewById(R.id.department);
TextView startDate = (TextView) v.findViewById(R.id.startDate);
TextView endDate = (TextView) v.findViewById(R.id.endDate);
TextView hospitalName = (TextView) v.findViewById(R.id.hospitalName);
hospitalName.setText(empHistory.getHospital());
TextView departmentName = (TextView) v.findViewById(R.id.departmentName);
departmentName.setText(empHistory.getDepartment());
TextView startDate1 = (TextView) v.findViewById(R.id.startDate1);
startDate1.setText(empHistory.getStartDate());
TextView endDate1 = (TextView) v.findViewById(R.id.endDate1);
endDate1.setText(empHistory.getEndDate());
hospital.setVisibility(View.VISIBLE);
department.setVisibility(View.VISIBLE);
startDate.setVisibility(View.VISIBLE);
endDate.setVisibility(View.VISIBLE);
return v;
}
}
//this is where i populated the ListView
private void populateEmploymentHistoryList() {
listEmployeeHistory = (ListView) findViewById(R.id.listEmployeeHistory);
empHistory = dbHelper.getAllEmploymentHistory();
employmentHistoryAdapter = new EmploymentHistoryAdapter(empHistory,this);
listEmployeeHistory.setAdapter(employmentHistoryAdapter);
}
//this is my Layout file where i added the ListView and I have the custom design for list_row
<android.support.v7.widget.CardView
android:id="#+id/employmentHistoryCard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="#dimen/card_margin"
android:layout_marginLeft="#dimen/card_margin"
android:layout_marginRight="#dimen/card_margin">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/employmentHistory"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:background="#E0E0E0"
android:gravity="center"
android:text="Employment History"
android:textAppearance="#style/TextAppearance.AppCompat.Title"
android:textColor="#4A148C" />
<TextView
android:id="#+id/addEmployment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/employmentHistory"
android:layout_marginTop="15dp"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:drawableLeft="#drawable/ic_add"
android:drawablePadding="20dp"
android:drawableStart="#drawable/ic_add"
android:paddingLeft="30dp"
android:text="Add Employment"
android:textColor="#0e89d0" />
<ListView
android:id="#+id/listEmployeeHistory"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/addEmployment">
</ListView>
</RelativeLayout>
</android.support.v7.widget.CardView>
You need to specify certain height for ListView in the xml code. WRAP_CONTENT will not expand your ListView when data is inflated into it. Specify some height like 200dp or something.
first record content appear and the other records not appear untill i scroll the list,So if this list has 3 records which mean that i can't scroll so the first record content only appeared
reocrd 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"
android:background="#ffffffff">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Basket ID: "
android:layout_alignParentTop="true"
android:id="#+id/basketIDt"
android:padding="10dp"
android:textSize="20dp"
android:textColor="#color/abc_input_method_navigation_guard"
android:paddingTop="30dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="text"
android:layout_alignParentTop="true"
android:id="#+id/basketID"
android:layout_toRightOf="#+id/basketIDt"
android:padding="10dp"
android:textSize="20dp"
android:textColor="#color/abc_input_method_navigation_guard"
android:paddingTop="30dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="100dp"
android:text="text"
android:id="#+id/description"
android:layout_below="#+id/basketID"
android:textSize="15dp"
android:layout_centerHorizontal="true"/>
listview Activity
<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:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
android:background="#color/abc_search_url_text_normal"
tools:context="com.example.pc_orbit.myapplication.Employee.BasketList">
<ListView
android:layout_width="match_parent"
android:layout_height="400dp"
android:id="#+id/lv">
</ListView>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Scan QRCode"
android:background="#color/button_material_dark"
android:id="#+id/scan"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:textColor="#fffffb6b" />
ListAdapter
public class BasketListAdapter extends ArrayAdapter<BasketRecord> {
LayoutInflater mInflater;
Context context;
TextView basketID;
TextView description;
String latitude, longitude;
String citizenEmail;
String basketIDString ,descriptionString;
private List<BasketRecord> items = new ArrayList<BasketRecord>();
public BasketListAdapter(Context context, int resource, List<BasketRecord> items) {
super(context, resource, items);
this.context = context;
this.items= items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (null == convertView) {
RelativeLayout view = (RelativeLayout) RelativeLayout.inflate(this.context,
R.layout.basketsrecord, null);
Log.d("SeenDroid", String.format("Get view %d", position));
TextView id = new TextView(view.getContext());
description= new TextView(view.getContext());
latitude = this.items.get(position).getLatitude();
longitude = this.items.get(position).getLongitude();
citizenEmail= this.items.get(position).getCitizenEmail();
basketIDString =this.items.get(position).getBasketID();
descriptionString=this.items.get(position).getDescription();
view.addView(id);
view.addView(description);
return view;
} else {
RelativeLayout view = (RelativeLayout) convertView;
basketID = (TextView) view.getChildAt(1);
description= (TextView) view.getChildAt(2);
basketID.setText(this.items.get(position).getBasketID());
description.setText(this.items.get(position).getDescription());
latitude = this.items.get(position).getLatitude();
longitude = this.items.get(position).getLongitude();
citizenEmail= this.items.get(position).getCitizenEmail();
basketIDString = this.items.get(position).getBasketID();
descriptionString=this.items.get(position).getDescription();
return convertView;
}
}
}
You are not setting the data when convert view is null. Which it would be in the first few passes. You only set it in the else condition. One quick fix would be to set the convert view to the view that you are creating instead of returning it at the end of your if and then get rid off the else (not whats in it) and keep the remaining code.
It would look something like this
public View getView(int position, View convertView, ViewGroup parent) {
if (null == convertView) {
RelativeLayout view = (RelativeLayout) RelativeLayout.inflate(this.context,
R.layout.basketsrecord, null);
Log.d("SeenDroid", String.format("Get view %d", position));
TextView id = new TextView(view.getContext());
description = new TextView(view.getContext());
//I am not sure what your logic was here so I just left it in
latitude = this.items.get(position).getLatitude();
longitude = this.items.get(position).getLongitude();
citizenEmail = this.items.get(position).getCitizenEmail();
basketIDString = this.items.get(position).getBasketID();
descriptionString = this.items.get(position).getDescription();
view.addView(id);
view.addView(description);
convertView = view;
}
RelativeLayout view = (RelativeLayout) convertView;
basketID = (TextView) view.getChildAt(1);
description = (TextView) view.getChildAt(2);
basketID.setText(this.items.get(position).getBasketID());
description.setText(this.items.get(position).getDescription());
latitude = this.items.get(position).getLatitude();
longitude = this.items.get(position).getLongitude();
citizenEmail = this.items.get(position).getCitizenEmail();
basketIDString = this.items.get(position).getBasketID();
descriptionString = this.items.get(position).getDescription();
return convertView;
}
Note this is only a quick fix. You should probably clean it to make more readable/reduce lines of code
A will advice you to use BaseAdapter instead ArrayAdapter, some methods whill help to count items and get id dinamically;
And to use 'Holders'
class viewHolderItem{
TextView id;
TextView description;
}
public class itemAdapter extends BaseAdapter{
Activity activity;
ArrayList<Item> listItems;
public itemAdapter(Activity activity,ArrayList<Item> listItems){
this.activity=activity;
this.listItems=listItems;
}
#Override
public int getCount() {
return listItems.size();
}
#Override
public Object getItem(int position) {
return listItems.get(position);
}
#Override
public long getItemId(int position) {
//it´s recomended to use an identifiyer for each item on list
//
//return listItems.get(position).getItemId();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
final viewHolderItem viewhold;
if(vi == null|| !(vi.getTag() instanceof viewHolderItem)) {
LayoutInflater inflater = (LayoutInflater) actividad.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
vi = inflater.inflate(R.layout.basketsrecord,null);
viewhold=new viewHolderItem();
viewhold.id=(TextView) vi.findViewById(R.id.basketID);
viewhold.description=(TextView)vi.findViewById(R.id.description);
//all other view elements of your xml
//...
}
else{
viewhold = (viewHolderItem)vi.getTag();
}
final Item item = listItems.get(position);
viewhold.id.setText(item.getBasketID());
viewhold.description.setText(item.getDescription);
//all other attributes of your object
//..
return (vi);
}
}
Well I do not know what should be the proper title for the question , but my problem is quite amazing, do not know is it possible or not. Here is my question
I have series of images and I want to set them in a ListView. following is a ListView row Xml.(named anim_list_row)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="100"
>
<ImageView
android:layout_width="0dp"
android:layout_height="350dp"
android:scaleType="fitXY"
android:id="#+id/iv_dummy_left"
android:layout_marginLeft="5dp"
android:layout_weight="50"/>
<ImageView
android:layout_width="0dp"
android:layout_height="350dp"
android:scaleType="fitXY"
android:id="#+id/iv_dummy_right"
android:layout_weight="50"
android:layout_marginRight="5dp"/>
</LinearLayout>
in this you can see that I want to set the 2 different images in two different let say left and right ImageView. Following is my adapter class
public class MListAdapter extends BaseAdapter {
private Context context;
private ArrayList<AnimListItems> mAnimListItems;
public MListAdapter(Context context, ArrayList<AnimListItems> mAnimListItems){
this.context = context;
this.mAnimListItems = mAnimListItems;
}
#Override
public int getCount() {
return mAnimListItems.size();
}
#Override
public Object getItem(int position) {
return navDrawerItems.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
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.anim_list_row, null);
}
ImageView imgIconLeft = (ImageView) convertView.findViewById(R.id.iv_dummy_left);
ImageView imgIconRight = (ImageView) convertView.findViewById(R.id.iv_dummy_right);
//TextView txtTitle = (TextView) convertView.findViewById(R.id.title);
imgIconLeft.setImageResource(navDrawerItems.get(position).getIcon());
//if I do not do +1 here it sets same image to both left and right ImageView
imgIconRight.setImageResource(navDrawerItems.get(position+1).getIcon());
// txtTitle.setText(navDrawerItems.get(position).getTitle());
return convertView;
}
}
so here is problem this list view is working but it is assigning the same images to both ImageView in the row. and if I do +1 as following
imgIconRight.setImageResource(navDrawerItems.get(position+1).getIcon())
then it helps in changing the image view at right side in the row, but the 2nd row repeat the image in its first imageview (I mean the image in the left ImageView of the 2nd row is same as the image in right ImageView of first row.)
So what is a solution of
Repeating images in a rows.
And How can I get each ImageView id and its resourceid of the image so that I can come to know which image has been clicked. And then I can able to set that image into another activity's ImageView. I mean I wanted to know which image has been clicked by the user , so I want to set same image in the ImageView of other activity.
Hello If you want to user one single array then i have made one demo example for your problem quickly i think it will help you.
MainActivity.java
public class MainActivity extends ActionBarActivity {
Item item;
ArrayList<Object> obj = new ArrayList<Object>();
MListAdapter adapter;
ListView lv;
int[] arrEnabledImageIds = new int[] { R.drawable.ic_launcher,
R.drawable.ic_delete_icon, R.drawable.ic_delete_icon,
R.drawable.ic_launcher, R.drawable.ic_delete_icon,
R.drawable.ic_launcher };
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView) findViewById(R.id.listView1);
for (int i = 0; i < arrEnabledImageIds.length; i++) {
Item itemInfo = new Item();
itemInfo.image1 = arrEnabledImageIds[i];
i++;
itemInfo.image2 = arrEnabledImageIds[i];
obj.add(itemInfo);
}
adapter = new MListAdapter(this, R.layout.row, obj);
lv.setAdapter(adapter);
}
}
activity_main.xml
<LinearLayout 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:orientation="vertical"
>
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
Item.java
public class Item implements Serializable {
public static final long serialVersionUID = 1L;
public int image1;
public int image2;
}
row.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="horizontal" >
<ImageView
android:id="#+id/ivLeft"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_launcher" />
<ImageView
android:id="#+id/ivRight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_launcher" />
</LinearLayout>
MListAdapter.java
public class MListAdapter extends ArrayAdapter<Object> {
private Context context;
int resId;
private ArrayList<Object> mAnimListItems;
public MListAdapter(Context context, int textViewResourceId,
ArrayList<Object> mAnimListItems) {
super(context, textViewResourceId, mAnimListItems);
this.resId = textViewResourceId;
this.context = context;
this.mAnimListItems = mAnimListItems;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(resId, null);
}
ImageView imgIconLeft = (ImageView) convertView
.findViewById(R.id.ivLeft);
ImageView imgIconRight = (ImageView) convertView
.findViewById(R.id.ivRight);
// TextView txtTitle = (TextView) convertView.findViewById(R.id.title);
Item item = (Item) mAnimListItems.get(position);
imgIconLeft.setImageResource(item.image1);
// if I do not do +1 here it sets same image to both left and right
// ImageView
imgIconRight.setImageResource(item.image2);
// txtTitle.setText(navDrawerItems.get(position).getTitle());
return convertView;
}
}
try to use two different array/arraylist to store left and rightside images seprately.
settag as l+position for left image
settag as r+position for right image
you can identify the clicked image by
imgIconLeft.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(v.getTag.toString().contains("l"){
// then it's a left button.
String position=v.getTag.toString().subString(1,v.getTag.toString().length()-1);
// to get position
}
});
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);