I have a donorview class which extends linearlayout which is as follows:
public class donorview extends LinearLayout {
private TextView donortext;
private String donorstr;
private ImageButton call;
private ImageButton msg;
private String donornumber;
private Context context1;
private View convertView;
public donorview(Context context, String donorname1, String donornum) {
super(context);
context1 = context;
// TODO Auto-generated constructor stub
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.listformat, null);
convertView.setClickable(true);
donortext = (TextView) findViewById(R.id.donornametext);
call = (ImageButton) findViewById(R.id.call);
msg = (ImageButton) findViewById(R.id.msg);
System.out.println("donorname:"+donorname1);
System.out.println("donornum:"+donornum);
donortext.setText(donorname1);
System.out.println("after setting text");
donorstr = donorname1;
donornumber = donornum;
}
void onClickCall(){
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:" + donornumber));
convertView.getContext().startActivity(callIntent);
}
public void setdonorname(String donorname12) {
donortext.setText(donorname12);
}
public String getdonorname() {
return this.donorstr;
}
}
I get a NullPoinerException as
java.lang.NullPonintereException
at com.wglxy.example.dash1.donorview.<init>(donorview.java:35)
while setting the text of the textview donortext. My XML layout of the listformat is
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:id="#+id/linerlayout1"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView android:id="#+id/donornametext" android:layout_height="wrap_content"
android:layout_width="wrap_content" android:layout_weight="1" android:text="a"/>
<ImageButton android:layout_width="wrap_content" android:id="#+id/call"
android:layout_height="wrap_content" android:contentDescription="#string/description_about"
android:src="#drawable/call" android:onClick="onClickCall"
android:background="#ffffff" />
<ImageButton android:layout_width="wrap_content" android:id="#+id/msg"
android:layout_height="wrap_content" android:contentDescription="#string/description_about"
android:src="#drawable/msg" android:onClick="onClickMsg"
android:background="#ffffff" />
</LinearLayout>
I dont understand what I am doing wrong. The list that is being displayed is empty. When i am printing the donorname and donornum it is being printed but the custom list displayed is empty.I have been trying to figure it out from a long time. Could anyone please help me with this?
My adapter code is as follows
public class donorAdapter extends BaseAdapter {
private Activity activity;
ArrayList<String> names = new ArrayList<String>();
ArrayList<String> nums = new ArrayList<String>();
private Context context;
private String strnum;
private String strname;
private static LayoutInflater inflater = null;
public donorAdapter(Context context, Activity a, ArrayList<String> names,
ArrayList<String> nums) {
this.context = context;
activity = a;
this.names = names;
this.nums = nums;
inflater = LayoutInflater.from(activity);
}
public int getCount() {
return names.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
donorview fv;
if (convertView == null) {
System.out.println("inside getview:"+names.get(position).toString());
strname=names.get(position).toString();
strnum=nums.get(position).toString();
System.out.println("inside getview:"+nums.get(position).toString());
fv = new donorview(context, strname,strnum);
convertView = fv;
}
else {
((donorview) convertView).setdonorname(names.get(position)
.toString());
}
convertView.setClickable(true);
convertView.setFocusable(true);
return convertView;
}
}
-Thanks in advance
You should use
donortext = (TextView)convertView.findViewById(R.id.donornametext);
and also replace your code by
convertView = inflater.inflate(R.layout.listformat, this);
Replace
findViewById
with
convertView.findViewById()
you use findViewById, when you have already set the content for the activity, in your case you did not , so you have to specify which view it has to look to get the id. You have to do the same for the rest of your views.
Related
I have custom adapter for ListView. The ListView is in activity_main.xml and I have a ImageView in CustomAdapter layout which is populated with ListView using CustomAdapter.
My Question is I have to hide/show that image which is in custom layout with a button present in main layout. Like if there is 10 row in my ListView and 10 row have that image. I want to hide only for the particular row.
I hope you understand my question...Thanks in Advance
Here's my ListViewAdapter
public class ListViewAdapter extends ArrayAdapter<FileName> {
Context context;
LayoutInflater inflater;
List<FileName> filenames;
private SparseBooleanArray mSelectedItemsIds;
public ListViewAdapter(Context context,int resource,List<FileName> filenames) {
super(context, resource, filenames);
mSelectedItemsIds = new SparseBooleanArray();
this.context = context;
this.filenames = filenames;
inflater = LayoutInflater.from(context);
}
private class ViewHolder {
TextView filename;
TextView shorttext;
ImageView imageView;
}
public View getView(int position, View view, ViewGroup parent) {
final ViewHolder holder;
if (view == null) {
holder = new ViewHolder();
view = inflater.inflate(R.layout.listview_item, null);
// Locate the TextViews in listview_item.xml
holder.filename = (TextView) view.findViewById(R.id.item_title);
holder.shorttext = (TextView) view.findViewById(R.id.item_desc);
holder.imageView = (ImageView) view.findViewById(R.id.lock);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
// Capture position and set to the TextViews<br />
holder.filename.setText(filenames.get(position).getName());
holder.shorttext.setText(filenames.get(position).getShorttext());
return view;
}
}
name = filenames.get(position).getName(); //getting the positin from listview
filenames.set(name,FileName.isVisible = true); //getting error on isVisible
I have writen a Sample code and tested
MainActivity
public class MainActivity extends AppCompatActivity {
List<FileName> filenames;
DBhelper dBhelper;dBhelper
SQLiteDatabase sqLiteDatabase;
ListViewAdapter listViewAdapter;
ListView listView;
ImageView lock;
String name;
//temporary button i have added
Button lockBTN;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
listView = (ListView) findViewById(R.id.lv_filename);
lockBTN = (Button) findViewById(R.id.lock);
filenames = getResult();
listViewAdapter = new ListViewAdapter(this, filenames);
listView.setAdapter(listViewAdapter);
lockBTN.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//giving statically position is 2
int position = 2;
// when you press menu button or any other button
FileName fileName = filenames.get(position);
//here you can set true-Show and false-hide imageview
fileName.setVisible(true);
//and update the list
filenames.set(position, fileName);
listViewAdapter.notifyDataSetChanged();
}
});
}
//temporary data to show on listview
private List<FileName> getResult() {
List<FileName> fileNames = new ArrayList<>();
String[] nameArr = {"Name1", "Name2", "Name3"};
String[] shortTextArr = {"ShortText1", "ShortText2", "ShortText3"};
for(int i=0; i<nameArr.length;i ++){
FileName fileName = new FileName();
fileName.setName(nameArr[i]);
fileName.setShorttext(shortTextArr[i]);
//setting default is hide to imageview
fileName.setVisible(false);
fileNames.add(fileName);
}
return fileNames;
}
}
FileName
public class FileName {
private String name;
private String shorttext;
private boolean visible = true;
public String getName() {
return name;
}
public void setName(String _name) {
this.name = _name;
}
public String getShorttext() {
return shorttext;
}
public void setShorttext(String _shorttext) {
this.shorttext = _shorttext;
}
public boolean isVisible() {
return visible;
}
public void setVisible(boolean visible) {
this.visible = visible;
}
}
ListViewAdapter
public class ListViewAdapter extends BaseAdapter{
Context context;
LayoutInflater inflater;
List<FileName> filenames;
private SparseBooleanArray mSelectedItemsIds;
public ListViewAdapter(Context context, List<FileName> filenames) {
mSelectedItemsIds = new SparseBooleanArray();
this.context = context;
this.filenames = filenames;
inflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return filenames.size();
}
#Override
public Object getItem(int position) {
return filenames.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(int position, View view, ViewGroup parent) {
final ViewHolder holder;
if (view == null) {
holder = new ViewHolder();
view = inflater.inflate(R.layout.listview_item, null);
// Locate the TextViews in listview_item.xml
holder.filename = (TextView) view.findViewById(R.id.item_title);
holder.shorttext = (TextView) view.findViewById(R.id.item_desc);
holder.imageView = (ImageView) view.findViewById(R.id.lock);
//holder.filename.setPaintFlags(holder.filename.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
// Capture position and set to the TextViews<br />
holder.filename.setText(filenames.get(position).getName());
holder.shorttext.setText(filenames.get(position).getShorttext());
// check weather image is to show/hide
if (filenames.get(position).isVisible()) {
holder.imageView.setVisibility(View.VISIBLE);
} else {
holder.imageView.setVisibility(View.GONE);
}
return view;
}
private class ViewHolder {
TextView filename;
TextView shorttext;
ImageView imageView;
}
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="5dp"
android:orientation="vertical">
<ListView
android:id="#+id/lv_filename"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/lock"/>
<Button
android:id="#+id/lock"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Lock"/>
</RelativeLayout>
custom_list_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="1">
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/utilities_notepad_icon" />
<LinearLayout
android:layout_width="232dp"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_weight="0.77">
<TextView
android:id="#+id/item_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="1dp"
android:paddingTop="5dp"
android:text="Item Title"
android:textSize="16dp" />
<TextView
android:id="#+id/item_desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLength="35"
android:paddingBottom="5dp"
android:paddingTop="1dp"
android:text="Item Description"
android:textColor="#999"
android:textSize="10dp" />
</LinearLayout>
<ImageView
android:id="#+id/lock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/lo"
android:layout_marginTop="13sp" />
</LinearLayout>
Take a extra variable in your FileName class.
public class FileName {
public String name;
public String shortText;
public boolean visible = true; // Set the default value to true.
}
Now on external button click in your main layout, you might consider updating the list item accordingly. Just set the visible variable to false of that item you want to hide. Then call notifyDataSetChanged() on your adapter to reload the data.
And yes, in your adapter, just check the value of visible attribute and then decide to hide/show the ImageView. So the getView function of your adapter should look like this.
public View getView(int position, View view, ViewGroup parent) {
final ViewHolder holder;
if (view == null) {
holder = new ViewHolder();
view = inflater.inflate(R.layout.listview_item, null);
// Locate the TextViews in listview_item.xml
holder.filename = (TextView) view.findViewById(R.id.item_title);
holder.shorttext = (TextView) view.findViewById(R.id.item_desc);
holder.imageView = (ImageView) view.findViewById(R.id.lock);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
// Capture position and set to the TextViews<br />
holder.filename.setText(filenames.get(position).getName());
holder.shorttext.setText(filenames.get(position).getShorttext());
// Hide/Show the ImageView
if (filenames.get(position).visible) holder.imageView.setVisibility(View.VISIBLE);
else holder.imageView.setVisibility(View.GONE);
return view;
}
I would suggest you to use RecyclerView instead of ListView. RecyclerView got more performance than the ListView. Now a days all are using RecyclerView instead of old ListView, it is quite easy to use as well.
And for handling your case create a function to remove the file name you wanted to remove in the RecyclerViewAdapter class as below
removeImageView(position){
fileNames.remove(position);
this.notifyItemRemoved(position);
}
notifyItemRemoved call will refresh the position in the recycler view and you will also get a nice view removing animation out of the box.
I have a custom row item xml and a Activity xml which has a button, a textbox and a listview. Can anybody give me a very simple example on how this is done? I know i will need a adapter (what it extends i dont know) and update it from the button
I have tried getting the list view updated from the button with the editview text but cant get the adapter code to be hit. I am looking at base adapters now but cant help but feel this shouldn't be complicated and need so many override methods.
Activity class
public class InvitePlayers_Activity extends Activity {
ListViewAdapter emailAdapter = null;
ImageView imgView_mail;
ImageView imgView_confirm;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE); //remove title bar
setContentView(R.layout.activity_inviteplayers);
//Generate list View from ArrayList
displayListView();
}
private void displayListView() {
//assign controls
final ListView listView = (ListView) findViewById(R.id.listView_invitePlayers);
imgView_mail = (ImageView)findViewById(R.id.imgView_mail);
//Test data
ArrayList<String> inviteNew = new ArrayList<String>();
final ArrayList<ArrayList<String>> inviteList = new ArrayList<ArrayList<String>>();
emailAdapter = new ListViewAdapter(this,inviteList);
listView.setAdapter(emailAdapter);
// Assign adapter to ListView
listView.setTextFilterEnabled(true);
//Edit listeners
imgView_mail.setOnClickListener(new View.OnClickListener() {
public void onClick(View view)
{
//variables
final String enteredMail = "testListViewEntry";
final ArrayList<ArrayList<String>> inviteList = new ArrayList<ArrayList<String>>();
ArrayList<String> invite = new ArrayList<String>();
invite.add(0, enteredMail);//add first email
invite.add(1,"icon_invitestatussent.png"); //add first status icon
inviteList.add(invite);
emailAdapter.notifyDataSetChanged();
listView.setAdapter(emailAdapter);
}
});
}
}
Adapter class
public class ListViewAdapter extends BaseAdapter {
private Activity context;
ArrayList<ArrayList<String>> inviteDetails = new ArrayList<ArrayList<String>>();
public ListViewAdapter(Activity context, ArrayList<ArrayList<String>> inviteDetails ) {
this.inviteDetails = inviteDetails;
this.context = context;
}
#Override
public int getCount() {
return 0;
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
public View getView(int position, View view, ViewGroup parent){
//Inflater
LayoutInflater inflater = context.getLayoutInflater();
//get row view
if (view == null) {
LayoutInflater mInflater = (LayoutInflater)
context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
view = mInflater.inflate(R.layout.list_item_email, null);
}
//assign controls
final TextView textView_playerEmail = (TextView) view.findViewById(R.id.textView_playerEmail);
ImageView imgView_inviteStatus = (ImageView) view.findViewById(R.id.imgView_inviteStatus);
//Assign control values that are dynamic
textView_playerEmail.setText(inviteDetails.get(position).get(0));
imgView_inviteStatus.setImageResource(R.drawable.icon_invitestatussent);
return view;
}
public ArrayList<ArrayList<String>> addInvite(ArrayList<String> inviteDetails, ArrayList<ArrayList<String>> currentInvites)
{
currentInvites.add(inviteDetails);
return currentInvites;
}
#Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
}
}
Custom row xml
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:textSize="16sp"
android:id="#+id/textView_playerEmail"
android:textColor="#color/white"
android:text="item1">
</TextView>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imgView_inviteStatus" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imgView_remove"
android:src="#drawable/btn_cancel" />
Activity layout
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:weightSum="1"
android:gravity="left|center">
<ImageView
android:layout_width="45dp"
android:layout_height="34dp"
android:id="#+id/imgView_mail"
android:src="#drawable/btn_mail"
android:layout_weight="0.22"
android:padding="3dp" />
</LinearLayout>
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/listView_invitePlayers"
android:layout_gravity="center_horizontal" />
</LinearLayout>
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:id="#+id/btn_confirm"
android:src="#drawable/btn_confirm"
android:clickable="false"
android:adjustViewBounds="true"
android:layout_gravity="center_horizontal"
android:padding="2dp"
android:layout_weight="1" />
</LinearLayout>
From reading the description of the question I think you need to set custom adapter to show the elements in you listview. This is how you set the custom adapter for the listview:
public class Notes_list extends BaseAdapter
{
private Context mContext;
private ArrayList<String> id;
private ArrayList<String> firstName;
private ArrayList<String> lastName;
public Notes_list(Context c, ArrayList<String> id,ArrayList<String> fname, ArrayList<String> lname)
{
this.mContext = c;
this.id = id;
this.firstName = fname;
this.lastName = lname;
}
public int getCount() {
return id.size();
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int pos, View child, ViewGroup arg2) {
Holder mHolder;
LayoutInflater layoutInflater;
if (child == null) {
layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
child = layoutInflater.inflate(R.layout.custom_row, null);
mHolder = new Holder();
// mHolder.txt_id = (TextView) child.findViewById(R.id.txt_id);
mHolder.txt_fName = (TextView) child.findViewById(R.id.txt_fName);
mHolder.txt_lName = (TextView) child.findViewById(R.id.txt_lName);
child.setTag(mHolder);
} else
{
mHolder = (Holder) child.getTag();
}
// mHolder.txt_id.setText(id.get(pos));
mHolder.txt_fName.setText(firstName.get(pos));
mHolder.txt_lName.setText(lastName.get(pos));
return child;
}
public class Holder
{
// TextView txt_id;
TextView txt_fName;
TextView txt_lName;
}
}
now in your main activity where you have to call the list enter code like this:
private ListView userList;
private ArrayList<Employee> itemsList = new ArrayList<modelName>();
userList = (ListView) findViewById(R.id.List);
UserList disadpt = new UserList(MainActivity.this, itemsList);
userList.setAdapter(disadpt);
Hope it helps...
I am creating a android app in which i have list of channels(items) in a Custom GridView.
I have a favorite icon associated with each channel to add them in favorites list.
On click of this favorite icon the channel gets added to the Favorites List of channels.
When i use a android box remote i am not able to select the ImageView for favorite.
Instead the whole GridItem gets selected.
The single grid item is a LinearLayout which mainly has two ImageViews in it.
View code for a single grid-item of the gridview
<?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"
android:focusable="false"
android:clickable="true"
android:orientation="vertical" >
<ImageView
android:id="#+id/channelLogo"
android:layout_width="75dip"
android:layout_height="75dip"
android:layout_gravity="center"
android:focusable="false"
android:contentDescription="#string/app_name"/>
<TextView
android:id="#+id/channelName"
android:layout_width="fill_parent"
android:focusable="false"
android:layout_height="fill_parent"
android:gravity="center"
/>
<TextView
android:id="#+id/channelStatus"
android:layout_width="fill_parent"
android:focusable="false"
android:layout_height="fill_parent"
android:gravity="center"
/>
<ImageView
android:id="#+id/addToFavourite"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:focusableInTouchMode="true"
android:clickable="true"
android:focusable="false"
android:contentDescription="Add to favourites"
android:src="#drawable/addfavorites"
/>
</LinearLayout>
Code for my grid adapter where i handle the click of the ImageView (for adding a channel to favorite).
public class GridAdapter extends BaseAdapter {
private Context mContext;
private int resourceId;
private ArrayList<Item> itemList = new ArrayList<Item>();
private ArrayList<Category> categoryList = new ArrayList<Category>();
private int size;
private Integer[] mThumbIds;
private ViewGroup gridGroup;
private static final String PREFS_FAVOURITES = "favourites";
public GridAdapter(MainActivity c, int layoutResourceId, ArrayList<Item> data, int gsize) {
mContext = c;
resourceId = layoutResourceId;
itemList = data;
size = gsize;
mThumbIds = new Integer[gsize];
for(int i=0;i<mThumbIds.length;i++) {
mThumbIds[i] = R.drawable.ic_launcher;
}
}
#Override
public int getCount() {
return size;
}
#Override
public Object getItem(int arg0) {
return mThumbIds[arg0];
}
#Override
public long getItemId(int arg0) {
return arg0;
}
class ViewHolder {
ImageView imageUrl;
TextView channelNameTxt;
TextView channelStatusTxt;
ImageView imgFavourite;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
String contextClass = mContext.getClass().toString();
ViewHolder holder;
gridGroup = parent;
View grid = null;
if(convertView==null){
grid = new View(mContext);
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
if (contextClass.contains("MainActivity") || contextClass.contains("FavoriteActivity")) {
grid = inflater.inflate(R.layout.grid_item, parent, false);
}
}else{
grid = (View)convertView;
return grid;
}
if (contextClass.contains("MainActivity")) {
if (position < itemList.size()) {
holder = new ViewHolder();
holder.channelNameTxt = (TextView) grid
.findViewById(R.id.channelName);
String channelName = itemList.get(position).getChannelName().replace("\n", "").replace("\r", "");
holder.channelNameTxt.setText(channelName);
holder.channelStatusTxt = (TextView) grid
.findViewById(R.id.channelStatus);
holder.channelStatusTxt
.setText(itemList.get(position).getStatus());
if(itemList.get(position).getStatus().equalsIgnoreCase("Online")) {
holder.channelStatusTxt.setTextColor(Color.GREEN);
} else if(itemList.get(position).getStatus().equalsIgnoreCase("Offline")) {
holder.channelStatusTxt.setTextColor(Color.RED);
}
holder.imageUrl = null;
try {
holder.imageUrl = (ImageView) grid
.findViewById(R.id.channelLogo);
holder.imageUrl.setTag(itemList.get(position).getImageUrl());
new DownloadImagesTask().execute(holder.imageUrl);
notifyDataSetChanged();
} catch (Exception ex) {
System.out.println(ex.toString());
}
final Item info = itemList.get(position);
holder.imgFavourite = (ImageView)grid.findViewById(R.id.addToFavourite);
holder.imgFavourite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
//GridView gridview1;
if(mContext.getClass().toString().contains("MainActivity")) {
GridView gv = (GridView)gridGroup;
final int position = gv.getPositionForView((View) v.getParent());
Toast.makeText(mContext, "Position is :" + position, Toast.LENGTH_SHORT).show();
SharedPreferences settings = mContext.getSharedPreferences(PREFS_FAVOURITES, 0);
String favourites = settings.getString("favourites", "");
Item clicked_item = itemList.get(position);
String sep1 = "<sep1>";
String sep = "<sep>";
String favourite = clicked_item.getChannelUrl()+sep1+clicked_item.getChannelName()+sep1+clicked_item.getStatus()+sep1+"Favorite"+sep1+clicked_item.getImageUrl()+sep;
favourite = favourite.replace("\n", "").replace("\r", "");
if(!favourites.contains(favourite))
favourites = favourites+favourite;
SharedPreferences.Editor editor = settings.edit();
editor.putString("favourites", favourites);
editor.commit();
}
}
});
grid.setTag(holder);
}
}
return grid;
}
This works fine on a android phone.
I have a list view which displays only one record always, I've traced my program and find that there are 3 records in my arrayList which I'm passing to the listView adapter. After tracing into getView of list view I find that It executes more that 3 times with position of 0!
I have no idea what's the problem, please help me if you can.
activity_news.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"
android:background="#color/background"
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=".News" >
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ListView
android:id="#+id/lvNews"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp" />
</ScrollView>
</RelativeLayout>
this is row template for listView: news_row.xml
<?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="wrap_content"
android:background="#drawable/message_row_style"
android:layout_gravity="right"
android:gravity="right"
android:orientation="vertical" >
<LinearLayout
android:layout_marginTop="50dp"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="horizontal">
<TextView
android:id="#+id/txtTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textColor="#color/dark_purple"
android:layout_gravity="right"
android:gravity="right"
android:background="#color/red"
/>
<TextView
android:id="#+id/txtDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/dark_purple"
android:layout_gravity="right"
android:background="#color/blue"
android:gravity="right" />
</LinearLayout>
</LinearLayout>
newsAdapter.java:
public class NewsAdapter extends BaseAdapter{
private Context context;
private ArrayList<News> list;
private Activity activity;
public NewsAdapter(Context c,Activity activity,ArrayList<News> l) {
Log.d("Ehsan", "News Adapter Constructor");
context = c;
list = l;
this.activity = activity;
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int i) {
return list.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row = inflater.inflate(R.layout.news_row, parent,false);
TextView title = (TextView) row.findViewById(R.id.txtTitle);
TextView date = (TextView) row.findViewById(R.id.txtDate);
News temp = list.get(position);
title.setText(temp.getTitle());
date.setText(temp.getsDate());
title.setTag(temp.getid());
title.setOnClickListener(onClickListener);
return row;
}
private OnClickListener onClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
String date = null,title = null,description = null;
int id=1;
Intent i = null;
News news = new News(activity);
news.load(id);
date = news.getsDate()+" - ";
title = news.getTitle();
description = news.getDescription();
i = new Intent(activity,ShowInfo.class);
i.putExtra("date", date);
i.putExtra("title", title);
i.putExtra("description", description);
activity.startActivity(i);
activity.finish();
}
};
}
Do following changes in your getView
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
ViewHolder holder=new ViewHolder();
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.news_row, parent,false);
TextView title = (TextView) row.findViewById(R.id.txtTitle);
TextView date = (TextView) row.findViewById(R.id.txtDate);
convertView.setTag(holder);
}
ViewHolder hold=(ViewHolder)convertView.getTag();
News temp = list.get(position);
hold.title.setText(temp.getTitle());
hold.date.setText(temp.getsDate());
title.setOnClickListener(onClickListener);
return row;
}
add this class in your adapter file
static class ViewHolder
{
TextView title;
TextView date;
}
You should call super in the constructor of your adapter change your adapter as following:
public class NewsAdapter extends ArrayAdapter<News>{
private Context context;
private ArrayList<News> list;
private Activity activity;
public NewsAdapter(Context c,Activity activity,ArrayList<News> l) {
super(c,-1,l);//<-- **pass your item list to super**
Log.d("Ehsan", "News Adapter Constructor");
context = c;
list = l;
this.activity = activity;
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int i) {
return list.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row = inflater.inflate(R.layout.news_row, parent,false);
TextView title = (TextView) row.findViewById(R.id.txtTitle);
TextView date = (TextView) row.findViewById(R.id.txtDate);
News temp = list.get(position);
title.setText(temp.getTitle());
date.setText(temp.getsDate());
title.setTag(temp.getid());
title.setOnClickListener(onClickListener);
return row;
}
private OnClickListener onClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
String date = null,title = null,description = null;
int id=1;
Intent i = null;
News news = new News(activity);
news.load(id);
date = news.getsDate()+" - ";
title = news.getTitle();
description = news.getDescription();
i = new Intent(activity,ShowInfo.class);
i.putExtra("date", date);
i.putExtra("title", title);
i.putExtra("description", description);
activity.startActivity(i);
activity.finish();
}
};
}
I have a custom listView with three textViews. The data comes from a class with three ArrayLists, two of which are strings and the last one is an Integer. I have no problems populating and adding items to the list as I saw that when I displayed the ArrayList values on logCat via log.d, all three ArrayLists had their respectful items.
It seems to me that there is something wrong with the way I display data.
Here are the files:
list_row_layout.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/variant"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="variant" />
<TextView
android:id="#+id/quantity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text="quantity" />
<TextView
android:id="#+id/unit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginRight="221dp"
android:layout_toLeftOf="#+id/quantity"
android:text="unit" />
</RelativeLayout>
Here is the part in my activity_order_form.xml that has the listView element.
<RelativeLayout
android:id="#+id/relativeLayout3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_below="#+id/relativeLayout2"
android:orientation="vertical" >
<TextView
android:id="#+id/textViewVariantB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="94dp"
android:text="Variant"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/textViewUnit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginRight="123dp"
android:text="Unit"
android:textAppearance="?android:attr/textAppearanceLarge" />
<ListView
android:id="#+id/listViewProductOrder"
android:layout_width="match_parent"
android:layout_height="350dp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_below="#+id/textViewVariantB" >
</ListView>
</RelativeLayout>
Here is the class where the ArrayList are stored.
public class CurrentOrderClass {
private String productName;
//ArrayLists
private ArrayList<String> variantArray = new ArrayList<String>();
private ArrayList<String> unitArray = new ArrayList<String>();
private ArrayList<Integer> quantityArray = new ArrayList<Integer>();
//TODO ArrayList functions
public ArrayList<String> getUnitArray() {
return unitArray;
}
public void setUnitArray(ArrayList<String> unitArray) {
this.unitArray = unitArray;
}
public void addToUnitArray(String unit){
this.unitArray.add(unit);
}
public ArrayList<Integer> getQuantityArray() {
return quantityArray;
}
public void setQuantityArray(ArrayList<Integer> quantityArray) {
this.quantityArray = quantityArray;
}
public void addToQuantityArray(int quantity){
this.quantityArray.add(quantity);
}
public ArrayList<String> getVariantArray() {
return variantArray;
}
public void setVariantArray(ArrayList<String> variantArray) {
this.variantArray = variantArray;
}
public void addToVariantArray(String variantArray){
this.variantArray.add(variantArray);
}
}
Here is the CustomListAdapter.java file
public class CustomListAdapter extends BaseAdapter {
private ArrayList<CurrentOrderClass> listData;
private LayoutInflater layoutInflater;
public CustomListAdapter(Context context, ArrayList<CurrentOrderClass> listData) {
this.listData = listData;
layoutInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return listData.size();
}
#Override
public Object getItem(int position) {
return listData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.list_row_layout, null);
holder = new ViewHolder();
holder.variantView = (TextView) convertView.findViewById(R.id.variant);
holder.unitView = (TextView) convertView.findViewById(R.id.unit);
holder.quantityView = (TextView) convertView.findViewById(R.id.quantity);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.variantView.setText(listData.get(position).getVariantArray().get(position).toString());
holder.unitView.setText(listData.get(position).getUnitArray().get(position).toString());
holder.quantityView.setText(String.valueOf(listData.get(position).getQuantityRow()));
return convertView;
}
static class ViewHolder {
TextView variantView;
TextView unitView;
TextView quantityView;
}
public void setListData(ArrayList<CurrentOrderClass> data){
listData = data;
}
}
This is part of my OrderForm.java activity, this shows the onCreate and the method that populates the listView.
public class OrderForm extends Activity {
public TextView tv;
private int variantPosition;
CustomListAdapter customListAdapter;
CurrentOrderClass currentOrder = new CurrentOrderClass();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_order_form);
tv = (TextView)findViewById(R.id.textViewProduct);
//set variants here
popolateItem();
//set current order listview here
ArrayList image_details = getListData();
final ListView lv1 = (ListView) findViewById(R.id.listViewProductOrder);
customListAdapter = new CustomListAdapter(this, image_details);
lv1.setAdapter(customListAdapter);
}
private ArrayList getListData() {
ArrayList results = new ArrayList();
if(currentOrder.getQuantityArray().size() > 10){
loopUntil = currentOrder.getQuantityArray().size();
for(int i = 0; i < loopUntil; i++){
currentOrder.getQuantityArray();
currentOrder.getUnitArray();
currentOrder.getVariantArray();
results.add(currentOrder);
}
}
else{
loopUntil = 10;
for(int i = 0; i < loopUntil; i++){
currentOrder.getQuantityArray().add(i);
currentOrder.getUnitArray().add("Sample text here." + i);
currentOrder.getVariantArray().add("Another sample text here" + i);
results.add(currentOrder);
}
}
return results;
}
}
When I execute a Log.d statement to display the contents of my ArrayLists, it shows that my quantityArray has elements [0, 1, 2, 3, 4, 5, 6, 7, 9].
I know I can just convert quantityArray to an ArrayList from an ArayList, but I don't want to do that.
I think there's something wrong with my CustomListAdapter.
Any thoughts?
There is no where that you actually set the view, as in, it doesn't do anything, if convertView is null, you can't call any methods of it, convertView, if its is not null, will be ViewHolder in your context, what you need to do is have an object which is extending some type of view, instantiate it, give it methods to set the values, things like that.
For example here is what I use in an adapter that displays simple messages:
public class MessageView extends RelativeLayout {
private TextView mBody;
private String mBodyString = "";
private boolean mDrawn = false;
private boolean mLocal = false;
public MessageView(Context context) {
super(context);
this.drawView();
}
public MessageView(Context context, String body) {
super(context);
mBodyString = body;
this.drawView();
}
public MessageView(Context context, String body, boolean local) {
super(context);
mBodyString = body;
mLocal = local;
this.drawView();
}
private void drawView() {
if (mDrawn)
return;
mDrawn = true;
this.removeAllViews();
LayoutInflater li = (LayoutInflater) this.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
if(mLocal){
this.addView(li.inflate(R.layout.list_item_message_device, this, false),
params);
}else{
this.addView(li.inflate(R.layout.list_item_message_remote, this, false),
params);
}
mBody = (TextView) this.findViewById(R.id.tMessage);
mBody.setText(mBodyString);
}
public void setLocal(){
this.setLocal(true);
}
public void setLocal(boolean local){
mLocal = local;
mDrawn = false;
this.drawView();
}
public void setMessage(String body){
mBodyString = body;
mBody.setText(mBodyString);
}
}
I got it.
I changed
holder.quantityView.setText(String.valueOf(listData.get(position).getQuantityRow()));
to
holder.quantityView.setText(String.valueOf(listData.get(position).getQuantityArray().get(position)));