Add custom layout to listview row - java

I have tried for a while now but I still can't seem to get it right. I can add a custom header to a listview but I can't add a custom row layout to a list. I want each row in the list to have the layout of the file "listitemrow.xml" but I can't seem to quite understand how to do that despite reading multiple tutorials.
Here is my code
public class PortfolioFragMent extends android.app.ListFragment{
private String[] ShareholdingNames;
private ListView mainListView ;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
ListView listView = new ListView(getActivity());
super.onCreate(savedInstanceState);
ViewGroup header = (ViewGroup)inflater.inflate(R.layout.listviewheader, listView, false);
listView.addHeaderView(header, null, false);
ViewGroup listrow = (ViewGroup)inflater.inflate(R.layout.listitemrow, listView, false);
//listView.add(listitemrow); I want to do something like this
ArrayAdapter<String> array = new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1);
setListAdapter(array);
ShareholdingNames= ShareholdingNames();
for (String str : ShareholdingNames)
array.add(str);
listView.setAdapter(array);
return listView;
}
private String[] ShareholdingNames(){
ShareholdingNames = new String[Portfolio.getPortfolio().count()];
for(int i=0; i < Portfolio.getPortfolio().count(); i++){
ShareholdingNames[i]= Portfolio.getPortfolio().getShareHolding(i).getName();
}
return ShareholdingNames;
}
public void onListItemClick(ListView l, View v, int position, long id) {
Intent intent = new Intent(getActivity().getApplicationContext(),
DetailShareHoldingActivity.class);
intent.putExtra("new_variable_name","value");
intent.putExtra("bookPositionInList",position);
startActivity(intent);
}
}

To do so you need to add your own custom adapter and add the line
ViewGroup listrow = (ViewGroup)inflater.inflate(R.layout.listitemrow, listView, false);
into the adapter's getView method..
public class ListAdapter extends ArrayAdapter<Item> {
public ListAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
// TODO Auto-generated constructor stub
}
private List<Item> items;
public ListAdapter(Context context, int resource, List<Item> items) {
super(context, resource, items);
this.items = items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi;
vi = LayoutInflater.from(getContext());
v = vi.inflate(R.layout.listitemrow, listView, false);
}
...
return v;
}
}

Related

In ListviewAdapter I dont know why getview() function not call

i want know why getview() function is not call
maybe override is wrong?
i want make custom listlayout
what's wrong in listviewadapter?
public class ListViewAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<Word> items;
public ListViewAdapter(Context mContext, ArrayList<Word> items) {
this.mContext = mContext;
this.items = items;
}
#Override
public int getCount() {
return items.size();
}
#Override
public Object getItem(int i) {
return items.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
if (view == null) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.wordlist_layout, viewGroup, false);
}
TextView wordview1 = view.findViewById(R.id.wordView1);
System.out.println("wordlist layout = " + items.get(i).w1);
wordview1.setText(items.get(i).w1);
return view;
}
// this is my Main activity code
private ArrayList<Word> items;
private ListViewAdapter listviewadapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = findViewById(R.id.submit_Button);
btn.setOnClickListener(view -> {
ListView word_listview = findViewById(R.id.Wordle_Word_List);
items = new ArrayList<Word>();
items.add(new Word('a'));
listviewadapter = new ListViewAdapter(getApplicationContext(), items);
word_listview.setAdapter(listviewadapter);
});
}
i dont know what is missing in my code
In ListviewAdapter I dont know why getview() function not call
I think your problem is the condition in its body, not the whole function. There is no need to check if it is null or not. you can simply inflate the view as mentioned in this article:
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.wordlist_layout, viewGroup, false);
TextView wordview1 = view.findViewById(R.id.wordView1);
System.out.println("wordlist layout = " + items.get(i).w1);
wordview1.setText(items.get(i).w1);
return view;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
view = LayoutInflater.from(mContext).inflate(R.layout.wordlist_layout, viewGroup, false);
TextView wordview1 = view.findViewById(R.id.wordView1);
wordview1.setText(items.get(i).w1);
return view;
}

Click listener for a button in a customised cell in a list view

I've created a customised list view for my Android app in order to add a Delete button for every cell to make the user able to delete rows from the list. The customised list view is working well but when I added a click listener for the button, the list view show empty cells instead of populating the data coming from the array.
Here is the getView code:
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View row = inflater.inflate(R.layout.row, parent, false);
Button deleteButt = (Button) row.findViewById(R.id.deleteButton);
deleteButt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(getActivity(), "delete me", Toast.LENGTH_SHORT).show();
}
});
return row;
}
I think the I should return something else not the row, but I have no idea what to return. When I think about it when I return the row it should show the rows filled with data. Note when I delete this piece of code, the list view is working well with showing the data.
This is the whole code of the adapter class
// Our adapter class
class MyAdapter extends ArrayAdapter<String> {
Context context;
String rNames[];
MyAdapter(Context c, String name[]) {
super(c, R.layout.row, R.id.customerName, name);
this.context = c;
this.rNames = name;
}
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View row = inflater.inflate(R.layout.row, parent, false);
Button deleteButt = (Button) row.findViewById(R.id.deleteButton);
deleteButt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(getActivity(), "delete me", Toast.LENGTH_SHORT).show();
}
});
return row;
}
}
And this is the whole code of the home fragment page
public class HomeFragment extends Fragment {
// creating an empty array. This is an array of objects (array of arrays).
final ArrayList<String[]> mainObjectsArray = new ArrayList<String[]>();
//final String[][] myFamily = new String[][];
// creating another array of the titles. If our main array is an array of strings we will not need this.
// Why?. ArrayAdapter doesn't accept an array of arrays it only accepts an array of Stings, so we had to create a special array for the titles and bring them from our main array.
final ArrayList<String> theNames = new ArrayList<String>();
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_home, null);
// creaing a list view and connect it to the list view we created in the XML file
// Note: we need to add (final) to be able to access them from inside the loop
final ListView myListView = (ListView) rootView.findViewById(R.id.myListView);
// Retrieving the data and filling the array with it
ParseQuery<ParseObject> query = ParseQuery.getQuery("Orders");
query.orderByDescending("updatedAt");
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> objects, ParseException e) {
if (e == null) {
//Log.i("findInBackground", "Retrieved: " + objects.size() + "objects");
if (objects.size() > 0) {
for (ParseObject object: objects) {
// Converting every object to an array of two itmes, title and body.
String[] artical = {object.getString("TheSavedOrder"), object.getString("mobileNumber"), object.getString("Name")};
// Adding the array to our main array so we will have an array of arrays
mainObjectsArray.add(artical);
//Log.i("This my family array: ", myFamily.toString());
}
// We will add only the names to the array (theNames). theTitles will be an array of strings so we can populate it in the list view.
for (int i = 0; i < mainObjectsArray.size(); i++){
theNames.add(mainObjectsArray.get(i)[2]);
//Log.i("Here are teh title: ", myFamily.get(i)[0]);
Log.i("Here is thti: ", theNames.get(i));
}
// Converting theNames from ArrayList to an array
String[] namesArray = new String[theNames.size()];
namesArray = theNames.toArray(namesArray);
// Applaying our adapter
MyAdapter adapter = new MyAdapter(getActivity(), namesArray);
myListView.setAdapter(adapter);
}
}
}
});
// When clicking on an item in the list view
myListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//Log.i("The body is: ", mainObjectsArray.get(position));
Intent intent = new Intent(getContext(), TheBody.class);
intent.putExtra("mobile", mainObjectsArray.get(position)[1]); // mainObjectsArray.get(position)[1] means we will pass the second item in every array which is the (mobileNumber).
intent.putExtra("order", mainObjectsArray.get(position)[0]);
startActivity(intent);
}
});
return rootView;
}
// Our adapter class
class MyAdapter extends ArrayAdapter<String> {
Context context;
String rNames[];
MyAdapter(Context c, String name[]) {
super(c, R.layout.row, R.id.customerName, name);
this.context = c;
this.rNames = name;
}
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View row = inflater.inflate(R.layout.row, parent, false);
Button deleteButt = (Button) row.findViewById(R.id.deleteButton);
deleteButt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(getActivity(), "delete me", Toast.LENGTH_SHORT).show();
}
});
return row;
}
}
}
This is the XML code of the fragment
<?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">
<ListView
android:id="#+id/myListView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
And finally this is the XML code of the customised cell
<?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:orientation="horizontal"
android:padding="16dp"
android:descendantFocusability="blocksDescendants">
<TextView
android:id="#+id/customerName"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:text="custoemr name"
android:textColor="#000"
android:layout_margin="5dp"
android:textSize="20sp"/>
<Button
android:id="#+id/deleteButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Delete"
/>
</LinearLayout>
Please help I've been struggling with this for some days!
Many thanks.
public View getView(final int position, View convertView, ViewGroup parent) {
View row = super.getView(position, convertView, parent);
Button deleteButt = (Button) row.findViewById(R.id.deleteButton);
deleteButt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(getActivity(), "delete me", Toast.LENGTH_SHORT).show();
} });
return row;
}
Pls also note that your list, rNames, is an array[] that is fixed size and cannot remove an individual item. You should use ArrayList if you want to implement the delete function.
Updated:
public class HomeFragment extends Fragment {
// creating an empty array. This is an array of objects (array of arrays).
ArrayList<MainObjects> mainObjectsList = new ArrayList<>();
ListView myListView;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_home, null);
// creaing a list view and connect it to the list view we created in the XML file
// Note: we need to add (final) to be able to access them from inside the loop
myListView = (ListView) rootView.findViewById(R.id.myListView);
// Retrieving the data and filling the array with it
ParseQuery<ParseObject> query = ParseQuery.getQuery("Orders");
query.orderByDescending("updatedAt");
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> objects, ParseException e) {
if (e == null) {
//Log.i("findInBackground", "Retrieved: " + objects.size() + "objects");
if (objects.size() > 0) {
for (ParseObject object : objects) {
// Converting every object to an array of two items, title and body.
//String[] artical = {object.getString("TheSavedOrder"), object.getString("mobileNumber"), object.getString("Name")};
MainObjects article = new MainObjects(object.getString("TheSavedOrder"), object.getString("mobileNumber"), object.getString("Name");
// Adding the array to our main array so we will have an array of arrays
mainObjectsList.add(article);
//Log.i("This my family array: ", myFamily.toString());
}
// Applying our adapter
MyAdapter adapter = new MyAdapter(getActivity(), mainObjectsList);
myListView.setAdapter(adapter);
}
}
}
});
// When clicking on an item in the list view
myListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//Log.i("The body is: ", mainObjectsList.get(position));
Intent intent = new Intent(getContext(), TheBody.class);
intent.putExtra("mobile", mainObjectsList.get(position).getMobileNumber());
intent.putExtra("order", mainObjectsList.get(position).getSavedOrder());
startActivity(intent);
}
});
return rootView;
}
class MainObjects {
String savedOrder = "", mobileNumber = "", name = "";
public MainObjects(String savedOrder, String mobileNumber, String name) {
this.savedOrder = savedOrder;
this.mobileNumber = mobileNumber;
this.name = name;
}
public String getSavedOrder() {
return savedOrder;
}
public String getMobileNumber() {
return mobileNumber;
}
public String getName() {
return name;
}
}
class MyAdapter extends ArrayAdapter<MainObjects> {
Context context;
LayoutInflater inflater;
ArrayList<MainObjects> rNames;
MyAdapter(Context c, ArrayList<MainObjects> name) {
super(c, R.layout.row, R.id.customerName, name);
this.context = c;
this.rNames = name;
inflater = getLayoutInflater();
}
public View getView(int position, View convertView, ViewGroup parent) {
View row = inflater.inflate(R.layout.row, parent, false);
TextView nameTv = (TextView) row.findViewById(R.id.customerName);
nameTv.setText(getItem(position).getName());
Button deleteButt = (Button) row.findViewById(R.id.deleteButton);
deleteButt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int pos = (int)view.getTag();
String msg = "Delete: " + pos + ". " + getItem(pos).getName() + " !!";
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
rNames.remove(pos);
notifyDataSetChanged();
//
// Codes to update permanent storage, e.g. files/server/db.
//
} });
deleteButt.setTag(position);
return row;
}
}
}

Java Android Data Binding ListView

I have problem with list view in data binding because I don't know how to set custom ArrayAdapter in view model, and how to add onItemClick listener in view model. Someone can show how to do this? Internet have really little information about this.
Simply set the adapter for the ListView. R.id.listview must refer to your ListView defined in the Layout obviously and R.layout.listviewrow to a layout that a row should have. Furthermore add a new Instance of onItemClickListener to the ListView.
MyCustomArrayAdapter adapter = new MyCustomArrayAdapter(getActivity(), R.layout.listviewrow);
ListView lv = (ListView) getActivity().findViewById(R.id.listview);
lv.setAdapter(adapter);
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//perform desired action here
}
} );
The Adapter itself should look something like this:
public class MyCustomArrayAdapter extends ArrayAdapter<Item> {
public MyCustomArrayAdapter(Context context, int resource) {
super(context, resource);
}
public MyCustomArrayAdapter(Context context, int resource, List<Item> items) {
super(context, resource, items);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi;
vi = LayoutInflater.from(getContext());
v = vi.inflate(resource, null);
}
Item item = getItem(position);
if (item != null) {
TextView tvFirstName = (TextView) v.findViewById(R.id.firstName);
TextView tvLastName = (TextView) v.findViewById(R.id.lastName);
if (tvFirstName != null) {
tvFirstName.setText(item.getFirstName());
}
if (tvLastName != null) {
tvLastName.setText(item.getLastName);
}
}
return v;
}

Refresh ListView Items upon button triggered

I was having some problem when trying to refresh the items in list view after the button was triggered. Here is how I populate the listview onCreate:
public class EventChat extends Fragment {
Context context;
View eventChat;
String userID, eventID;
private ListView listview;
public ArrayList<EventComment> _commentlist = new ArrayList<EventComment>();
TextView txtDisplayCommentBy, txtDisplayDateTime, txtDisplayCommentDesc,
txtEventChat;
Button btnChatSubmit;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
eventChat = inflater.inflate(R.layout.event_chat, container, false);
context = getActivity();
listview = (ListView) eventChat.findViewById(R.id.listview);
txtEventChat = (TextView) eventChat.findViewById(R.id.txtEventChat);
btnChatSubmit = (Button) eventChat.findViewById(R.id.btnChatSubmit);
btnChatSubmit.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
onSubmitChatClicked();
}
});
Intent i = getActivity().getIntent();
_commentlist = (ArrayList<EventComment>) i
.getSerializableExtra("eventCommentObj");
Event eventModel = (Event) i.getSerializableExtra("eventObj");
userID = "Gab";
eventID = eventModel.getEventID();
listview.setAdapter(new ListAdapter(getActivity()));
return eventChat;
}
private class ListAdapter extends BaseAdapter {
LayoutInflater inflater;
ViewHolder viewHolder;
public ListAdapter(Context context) {
inflater = LayoutInflater.from(context);
}
public int getCount() {
return _commentlist.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.eventchat_listview_row,
null);
viewHolder = new ViewHolder();
viewHolder.txt_dcommentBy = (TextView) convertView
.findViewById(R.id.txtDisplayCommentBy);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.txt_dcommentBy.setText(_commentlist.get(position)
.getCommentBy().trim());
return convertView;
}
}
private class ViewHolder {
TextView txt_dcommentBy;
TextView txt_ddateTime;
TextView txt_dcommentDesc;
}
}
When my button was triggered and insert a new record into database, at the same time, I wanted the list view items to be refreshed:
public void onSubmitChatClicked() {
EventComment commentModel = new EventComment();
String currentDate = EventDateTime.getCurrentDate();
String currentTime = EventDateTime.getCurrentTime();
String commentDesc = String.valueOf(txtEventChat.getText());
commentModel.setCommentBy(userID);
commentModel.setEventID(eventID);
commentModel.setCommentDate(currentDate);
commentModel.setCommentTime(currentTime);
commentModel.setCommentDesc(commentDesc);
new CreateCommentAsyncTask(context).execute(commentModel);
txtEventChat.setText("");
}
However, it does not refresh. Any ideas?
Thanks in advance.
Well this looks pretty straightforward.
First make your adapter a class member, so you can access it later:
private ListAdapter mAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
...
mAdapter = new ListAdapter(getActivity();
listview.setAdapter(mAdapter);
...
}
Then, when you submit the item, also add it to your ArrayList and update your adapter:
public void onSubmitChatClicked() {
EventComment commentModel = new EventComment();
String currentDate = EventDateTime.getCurrentDate();
String currentTime = EventDateTime.getCurrentTime();
String commentDesc = String.valueOf(txtEventChat.getText());
commentModel.setCommentBy(userID);
commentModel.setEventID(eventID);
commentModel.setCommentDate(currentDate);
commentModel.setCommentTime(currentTime);
commentModel.setCommentDesc(commentDesc);
// Add the new element to your DB
new CreateCommentAsyncTask(context).execute(commentModel);
// Add the new element to your current ArrayList
_commentlist.add(commentModel)
// Update theListView, by updating the adapter
mAdapter.notifyDataSetChanged();
txtEventChat.setText("");
}
EDIT:
Little more explanation:
When your fragment is created you are passed an array of EventComment items. I guess these are the elements from your DB. When you update the database, however, your ArrayList won't get updated, unless you reload the whole fragment. That's why you add the item to the DB, and to the list manually, and with notifyDataSetChanged, you force your adapter to update the ListView.
You cant do listview.setAdapter(new ListAdapter(getActivity())); to achieve this. You should create an instance of adapter and call adapter.add + adapter.notifyDataSetChanged
This is a very good tutorial :
http://www.vogella.com/tutorials/AndroidListView/article.html
http://www.javacodegeeks.com/2013/09/android-listview-with-adapter-example.html

Unable to get OnItemClickListener to function for Android in Java

I am fairly new to Java and have had little experience with listviews. I have been able to successfully add items to a listview with a custom list adapter. However, I now want to perform actions when each item is touched.
I have not been able to get the OnItemClickListener event to execute when a list item is touched, i am not sure where the problem lies.
Code:
public class FragmentA extends Fragment implements OnItemClickListener{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View V = inflater.inflate(R.layout.fragment_a, container, false);
ListView listView = (ListView)V.findViewById(R.id.list);
getData data = getData.getMyData();
CustomList adapter = new
CustomList(getActivity(), data.Headline.toArray(new String[data.Headline.size()]), data.Description.toArray(new String[data.Description.size()]), data.imageId.toArray(new Integer[data.imageId.size()]));
listView.setAdapter(adapter);
return V;
}
public void onItemClickListener(AdapterView<?> parent, View view, int position, long id)
{
Log.e("CLICKED","CLICKED");
}
}
Also if it helps, here is the code to the custom adapter class:
public class CustomList extends ArrayAdapter<String>{
private final Activity context;
private final String[] titleId;
private final String[] descriptionId;
private final Integer[] pictureid;
public CustomList(Activity context,
String[] Headline, String[] Description, Integer[] imageId) {
super(context, R.layout.single_row, Headline);
this.context = context;
this.titleId = Headline;
this.descriptionId = Description;
this.pictureid = imageId;
}
#Override
public View getView(int position, View view, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View rowView= inflater.inflate(R.layout.single_row, null, true);
TextView txtTitle = (TextView) rowView.findViewById(R.id.tvTitle);
TextView txtDescription = (TextView) rowView.findViewById(R.id.tvDescription);
ImageView imageView = (ImageView) rowView.findViewById(R.id.ivIcon);
txtTitle.setText(titleId[position]);
txtDescription.setText(descriptionId[position]);
imageView.setImageResource(pictureid[position]);
return rowView;
}
}
You have to use listView.setOnItemClickListener to link the callbacks to the view.
You can do as follows:
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View view,int pos, long id) {
//Your code here
}
});
But, in your case, as the activity already implements OnItemClickListener() you can simply:
listView.setOnItemClickListener(this);
Set the listener to your ListView:
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.e("CLICKED","CLICKED");
}
});

Categories