As the title says, I want to create a new list inside the Activity after clicking the RecyclerView. I am using JSON to get the data and the data inside apparently has a list for name, comments, and date time. I can set them into a TextView but that's not what I wanted. I need to show them as a list. The list should have name, comments, and date time. Thanks!
You need to use Custom Adapter instead of the ArrayAdapter. So that you can customize the view how ever you want.
For example in your case
row_item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp">
<!-- Name -->
<TextView
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:text="Marshmallow"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#android:color/black" />
<!-- Comments-->
<TextView
android:id="#+id/comments"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/name"
android:layout_marginTop="5dp"
android:text="Android 6.0"
android:textColor="#android:color/black" />
<!-- Date and Time-->
<TextView
android:id="#+id/dateandtime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/comments"
android:layout_marginTop="5dp"
android:text="11th August"
android:textColor="#android:color/black" />
</RelativeLayout>
DataModel.java
public class DataModel {
String name;
String comment,
String date;
public DataModel(String name, String type, String comment, String date) {
this.name=name;
this.comment=comment;
this.date=date;
}
public String getName() {
return name;
}
public String getComment() {
return comment;
}
public String getDate() {
return date;
}
}
And finally your Custom Adapter should be like below
CustomAdapter.java
public class CustomAdapter extends ArrayAdapter<DataModel> implements View.OnClickListener{
private ArrayList<DataModel> dataSet;
Context mContext;
// View lookup cache
private static class ViewHolder {
TextView txtName;
TextView txtComment;
TextView txtDate;
}
public CustomAdapter(ArrayList<DataModel> data, Context context) {
super(context, R.layout.row_item, data);
this.dataSet = data;
this.mContext=context;
}
#Override
public void onClick(View v) {
// your on click code
}
private int lastPosition = -1;
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
DataModel dataModel = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
ViewHolder viewHolder; // view lookup cache stored in tag
final View result;
if (convertView == null) {
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.row_item, parent, false);
viewHolder.txtName = (TextView) convertView.findViewById(R.id.name);
viewHolder.txtComment = (TextView) convertView.findViewById(R.id.comments);
viewHolder.txtDate = (TextView) convertView.findViewById(R.id.dateandtime);
result=convertView;
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
result=convertView;
}
viewHolder.txtName.setText(dataModel.getName());
viewHolder.txtComment.setText(dataModel.getComment());
viewHolder.txtDate.setText(dataModel.getDate());
viewHolder.info.setOnClickListener(this);
viewHolder.info.setTag(position);
// Return the completed view to render on screen
return convertView;
}
}
You have to set the adapter like this.
ArrayList<DataModel> dataModels; // then add your data into it
CustomAdapter adapter= new CustomAdapter(dataModels,getApplicationContext());
listView.setAdapter(adapter);
Check this example for better idea.
Related
I have a list view that is populated with an array of objects using a custom adapter and a row layout. The row displays the object's name, price, contains a button for changing the quantity and displays the total based on the quantity selected.
Example of list populated with 3 items
Here's the issue: I want to tell the list view that, for example, when the user clicks the quantity button in the 2nd row, I want to access the price and quantity values in that same row, & display the result in the total cell at the end of that specific row. I can't figure out how to do that. I'm confused because the button element has a single ID in the XML layout, so how do I distinguish, for example, the button in the 2nd row from the button in the 1st or last row since they're all duplicates?
I know the syntax for the OnClickListener method that will carry out the mathematical operation I need, I just don't know where in the program should I implement it. I've tried in the adapter, but only the button in the last row in the list functioned properly, not all of them. I've been searching and googling for a number of days now, and I've seen different approaches but I'm struggling with implementing them.
The best lead I got was about a method called ListView.getChildAt(index), which should return a specific row within the list based on an index, but how do I get the index of the row based on which button was clicked? This is the stackoverflow post where I read on the .getChildAt(index) method
I'll supply the code for my project below:
Code for the ShopActivity.java:
public class ShopActivity extends AppCompatActivity {
ListView listView;
ItemListAdapter adapter;
ArrayList<ShoppingItem> shoppingItems = new ArrayList<ShoppingItem>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.shop_activity);
shoppingItems.add(new ShoppingItem("Drink", "Water Bottle 1.5 ltr", 11));
shoppingItems.add(new ShoppingItem("Drink", "Pepsi 2 ltr", 10));
shoppingItems.add(new ShoppingItem("Drink", "Orange Juice 1.5 ltr", 7));
listView = (ListView) findViewById(R.id.itemListView);
adapter = new ItemListAdapter(this, R.layout.item_layout, shoppingItems);
listView.setAdapter(adapter);
}
Code for the adapter:
public class ItemListAdapter extends ArrayAdapter<ShoppingItem> {
private ArrayList<ShoppingItem> items;
private int layoutResourceId;
private Context context;
ItemHolder holder = new ItemHolder();
public ItemListAdapter(Context context, int layoutResourceId, ArrayList<ShoppingItem> items) {
super(context, layoutResourceId, items);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.items = items;
}
public static class ItemHolder {
public ShoppingItem shoppingItem;
public TextView itemName;
public TextView itemPrice;
public TextView itemQuantity;
public TextView totalPriceNumber;
public ImageButton plusButton;
public ImageButton minusButton;
}
#Override
public int getCount() {
return items.size();
}
#Override
public ShoppingItem getItem(int position) {
return items.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View rowView = convertView;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(layoutResourceId, parent, false);
TextView itemName = (TextView) rowView.findViewById(R.id.itemName);
TextView itemPrice = (TextView) rowView.findViewById(R.id.itemPrice);
TextView itemQuantity = (TextView) rowView.findViewById(R.id.itemQuantity);
TextView totalPriceNumber = (TextView) rowView.findViewById(R.id.totalPrice);
ImageButton plusButton = (ImageButton) rowView.findViewById(R.id.plusButton);
ImageButton minusButton = (ImageButton) rowView.findViewById(R.id.minusButton);
holder.itemName = itemName;
holder.itemPrice = itemPrice;
holder.itemQuantity = itemQuantity;
holder.totalPriceNumber = totalPriceNumber;
holder.plusButton = plusButton;
holder.minusButton = minusButton;
rowView.setTag(holder);
} else
holder = (ItemHolder) rowView.getTag();
holder.shoppingItem = items.get(position);
holder.itemName.setText(holder.shoppingItem.getItemName());
holder.itemPrice.setText(Double.toString(holder.shoppingItem.getItemPrice()));
holder.itemQuantity.setText(Integer.toString(holder.shoppingItem.getQuantity()));
holder.totalPriceNumber.setText(Double.toString(holder.shoppingItem.getItemPrice() * holder.shoppingItem.getQuantity()));
final int rowPosition = position;
holder.plusButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.shoppingItem = items.get(rowPosition);
int newQuantity = holder.shoppingItem.getQuantity();
newQuantity++;
holder.shoppingItem.setQuantity(newQuantity);
holder.itemQuantity.setText(Integer.toString(newQuantity));
holder.totalPriceNumber.setText(Double.toString(holder.shoppingItem.getItemPrice() * holder.shoppingItem.getQuantity()));
notifyDataSetChanged();
}
});
return rowView;
}
Code for the row XML:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="5dp">
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TableRow>
<CheckBox
android:layout_width="25dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center" />
<ImageView
android:id="#+id/imageBar"
android:layout_width="50dp"
android:layout_height="75dp"
android:layout_gravity="center"
android:src="#drawable/drink" />
<TextView
android:id="#+id/itemName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="3"
android:width="0dp" />
<TextView
android:id="#+id/itemPrice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:width="0dp"
android:gravity="center" />
<ImageButton
android:id="#+id/minusButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="0.3" />
<TextView
android:id="#+id/itemQuantity"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="0.4"
android:width="0dp"
android:gravity="center" />
<ImageButton
android:id="#+id/plusButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="0.3" />
<TextView
android:id="#+id/totalPrice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:width="0dp"
android:gravity="center" />
</TableRow>
</TableLayout>
Code for the ShoppingItem object:
public class ShoppingItem {
private String itemType;
private String itemName;
private double itemPrice;
private int quantity = 1;
public ShoppingItem(String itemType, String itemName, double itemPrice, int quantity) {
this.itemType = itemType;
this.itemName = itemName;
this.itemPrice = itemPrice;
this.quantity = quantity;
}
public String getItemType() {
return this.itemType;
}
public void setItemType(String itemType) {
this.itemType = itemType;
}
public String getItemName() {
return this.itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public double getItemPrice() {
return this.itemPrice;
}
public void setItemPrice(double itemPrice) {
this.itemPrice = itemPrice;
}
public int getQuantity() {
return this.quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
I'm new to the Android development scene.
Each of your rows represents a data set. For example you have a data class for an item.
data class Item(name: String, price: Double)
Add a field for the quantity quantity: Int
In the onClick for the plus button, increment the quantity variable for the item. For example like this:
// data set is something like this...
val dataSet = mutableListOf<Item>()
// creating the view for row i...
plusButton.onClick {
dataSet[i].quantity++
notifyItemChanged(i) // dont think this exists for ListView, but you can also just use notifyDataSetChanged, which will invalidate all rows
}
After incrementing the quantity, you trigger the notifyItemChanged method for the row you changed, this will trigger a UI update for the row, which will then represent your current data set.
You should add the onClick listener in the getView method, and instead of i use position to access the item in your data set.
EDIT:
In your getView() method try something like this:
final int rowPosition = position;
plusButton.setOnClickListener(new View.OnClickListener(View v) {
items.get(rowPosition).quantity++;
notifyDataSetChanged();
});
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.
So im new in Android programming I'm trying to make a custom ListView. I follow a tutorial on YouTube (https://www.youtube.com/watch?v=gAIB4fTm2BA) but i cant get it work on a fragment.
public class DriverFragment extends Fragment implements GeneralFragment {
ListView listView;
public DriverFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view;
view = inflater.inflate(R.layout.fragment_driver, container, false);
listView = (ListView) view.findViewById(R.id.driverList);
DriverAdapter driverAdapter = new DriverAdapter(getActivity().getApplicationContext(),R.layout.driver_listview);
listView.setAdapter(driverAdapter);
Driver a = new Driver("John Smith","Johnsmith#example.com","123");
driverAdapter.add(a);
return view;
}
Driver Adapter :
public class DriverAdapter extends ArrayAdapter {
ArrayList list = new ArrayList();
public DriverAdapter(Context context, int resource) {
super(context, resource);
}
static class Holder{
TextView NAME;
TextView EMAIL;
TextView PHONE;
}
public void add(Driver driver) {
list.add(driver);
super.add(driver);
}
#Override
public Object getItem(int position) {
return this.list.get(position);
}
public int getCount(){
return this.list.size();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row;
row = convertView;
Holder holder;
if(convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = layoutInflater.inflate(R.layout.driver_listview, parent, false);
holder = new Holder();
holder.NAME = (TextView) row.findViewById(R.id.driverName);
holder.EMAIL = (TextView) row.findViewById(R.id.driverMail);
holder.PHONE = (TextView) row.findViewById(R.id.driverPhone);
row.setTag(holder);
}else {
holder = (Holder) row.getTag();
}
Driver driver = (Driver)getItem(position);
holder.NAME.setText(driver.getName());
holder.EMAIL.setText(driver.getMail());
holder.PHONE.setText(driver.getPhone());
return row;
}
The XML
<?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">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="DriverName"
android:id="#+id/driverName"
android:padding="10dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="DriverMail"
android:id="#+id/driverMail"
android:layout_gravity="center_horizontal"
android:padding="10dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="DriverPhone"
android:id="#+id/driverPhone"
android:padding="10dp" />
first of all if you should really check out some good tutorial like
Using lists in Android (ListView) - Tutorial
http://www.vogella.com/tutorials/AndroidListView/article.html
Assuming everything is okay with your Fragment and it´s visible, lets focus on your Adapter. Since your DriverAdapter has it´s own ArrayList of data there is no point in calling super.add() in it´s add() method. You just call notifyDataSetChanged() to let the Adapter know that it should refresh the content on the UI. Try something like this..
public class DriverAdapter extends BaseAdapter {
ArrayList<Driver> data = new ArrayList();
public void add(Driver driver) {
data.add(driver);
notifyDataSetChanged();
}
public void addAll(List<Driver> drivers) {
data.addAll(drivers);
notifyDataSetChanged();
}
#Override
public Driver getItem(int position) {
return data.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public int getCount() {
return data.size();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder;
if (convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.item_driver_row, parent, false);
holder = new Holder();
holder.name = (TextView) convertView.findViewById(R.id.driverName);
holder.email = (TextView) convertView.findViewById(R.id.driverMail);
holder.phone = (TextView) convertView.findViewById(R.id.driverPhone);
} else {
holder = (Holder) convertView.getTag();
}
Driver driver = getItem(position);
holder.name.setText(driver.getName());
holder.email.setText(driver.getEmail());
holder.phone.setText(driver.getPhone());
convertView.setTag(holder);
return convertView;
}
static class Holder {
TextView name;
TextView email;
TextView phone;
}
}
My last answer didn't seem to help, I quickly put something together.
I would strongly advise reading up more on this topics since Lists and Adapters are an integral part of Android development and having an understanding of how it works is really helpful.
public class Driver {
private String name;
private String email;
private String phone;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
Fragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment, container, false);
ListView listView = (ListView) view.findViewById(R.id.listView);
Driver a = new Driver();
a.setName("Name");
a.setEmail("Email");
a.setPhone("Phone");
ArrayList<Driver> drivers = new ArrayList<>();
drivers.add(a);
DriverAdapter driverAdapter = new DriverAdapter(getActivity().getApplicationContext(),R.layout.driver_listview, drivers);
listView.setAdapter(driverAdapter);
return view;
}
Adapter
public class DriverAdapter extends ArrayAdapter<Driver> {
public DriverAdapter(Context context, int resource, List<Driver> objects) {
super(context, resource, objects);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row;
row = convertView;
Holder holder;
if(convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = layoutInflater.inflate(R.layout.driver_listview, parent, false);
holder = new Holder();
holder.name = (TextView) row.findViewById(R.id.driverName);
holder.email = (TextView) row.findViewById(R.id.driverMail);
holder.phone = (TextView) row.findViewById(R.id.driverPhone);
row.setTag(holder);
}else {
holder = (Holder) row.getTag();
}
Driver driver = getItem(position);
holder.name.setText(driver.getName());
holder.email.setText(driver.getEmail());
holder.phone.setText(driver.getPhone());
return row;
}
public class Holder {
protected TextView name;
protected TextView email;
protected TextView phone;
}
}
Adapter 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">
<TextView
android:id="#+id/driverName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="DriverName"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#android:color/black" />
<TextView
android:id="#+id/driverMail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="10dp"
android:text="DriverMail"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#android:color/black" />
<TextView
android:id="#+id/driverPhone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="DriverPhone"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#android:color/black" />
</LinearLayout>
If this doesn't help you, there is a problem with your fragment showing on the device. As I have tested this myself and it displays correctly on the screen.
Looks like you are setting your adapter to the ListView before you add anything to it, which is fine but you must call adapter.notifyDataSetChanged() in order to update the list with the new data.
Although, I would suggest changing how you create your adapter. Everytime I have used any sort of adapter, I create my list of data before and pass it in through the constructor. Then set it to my listview. So like:
View view;
view = inflater.inflate(R.layout.fragment_driver, container, false);
listView = (ListView) view.findViewById(R.id.driverList);
Driver a = new Driver("John Smith","Johnsmith#example.com","123");
ArrayList<Driver> drivers = new ArrayList();
drivers.add(a);
DriverAdapter driverAdapter = new DriverAdapter(getActivity().getApplicationContext(),R.layout.driver_listview, drivers);
listView.setAdapter(driverAdapter);
This is a only rough example of what I would do, I would advise you to read up on some examples from Google around this. Also read up on RecyclerViews instead of ListViews if possible.
https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html
https://www.bignerdranch.com/blog/recyclerview-part-1-fundamentals-for-listview-experts/
I'm new in android..
I would like to create the different views in Listview using Custom Adapter.
Please suggest me how I can do this.
In first row there will be a single Item and in second row there will be two item and so on..
Please Check the attached screen..
Thanks in advance
Define a custom layout of how you want the list row like this
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="#dimen/headerHeightCustRow"
android:background="#FFFFFF"
tools:ignore="HardcodedText" >
<TextView
android:id="#+id/txtName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dip"
android:layout_marginLeft="#dimen/viewSpace1"
android:text="Varun Mad"
android:textSize="#dimen/logout_textSize"
android:textStyle="bold"
android:textColor="#color/orange_normal" />
<TextView
android:id="#+id/txtCustId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginLeft="#dimen/viewSpace3"
android:layout_marginTop="#dimen/viewSpace3"
android:layout_marginRight="#dimen/viewSpace3"
android:text="10549"
android:layout_centerVertical="true"
android:textColor="#color/orange_normal"
android:textSize="15sp" />
<TextView
android:id="#+id/txtPhone"
android:layout_below="#id/txtName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/viewSpace1"
android:text="(886)677-8855"
android:textColor="#color/orange_normal"
android:textSize="#dimen/vsText" />
<TextView
android:id="#+id/txtEmail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/viewSpace1"
android:text="ggg#gmail.com"
android:textSize="#dimen/vsText"
android:layout_below="#id/txtPhone"
android:textColor="#color/orange_normal" />
<View
android:layout_width="fill_parent"
android:layout_height="0.5dip"
android:layout_alignParentBottom="true"
android:background="#color/greyDark" />
here is the adapter class
public class SearchCustomerAdapter extends BaseAdapter {
Context ctx;
LayoutInflater lInflater;
ArrayList<SearchCustomerItem> objects;
public SearchCustomerAdapter(Context context, ArrayList<SearchCustomerItem> products) {
ctx = context;
objects = products;
lInflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return objects.size();
}
#Override
public Object getItem(int position) {
return objects.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
view = lInflater.inflate(R.layout.search_cust_row, parent, false);
}
SearchCustomerItem p = getProduct(position);
((TextView) view.findViewById(R.id.txtName)).setText(p.customerName);
if (p.customerEmail.compareTo("anyType{}") == 0) {
((TextView) view.findViewById(R.id.txtEmail)).setText("");
} else {
((TextView) view.findViewById(R.id.txtEmail)).setText(p.customerEmail);
}
((TextView) view.findViewById(R.id.txtPhone)).setText(p.customerPhone);
((TextView) view.findViewById(R.id.txtCustId)).setText(p.customerId);
return view;
}
SearchCustomerItem getProduct(int position) {
return ((SearchCustomerItem) getItem(position));
}
#SuppressWarnings("unused")
ArrayList<SearchCustomerItem> getBox() {
ArrayList<SearchCustomerItem> box = new ArrayList<SearchCustomerItem>();
for (SearchCustomerItem p : objects) {
// if (p.box)
// box.add(p);
}
return box;
}
}
and the ITem Class
public class SearchCustomerItem {
public String customerName;
public String customerPhone;
public String customerEmail;
public String customerId;
public SearchCustomerItem(String _cName, String _cPhone, String _cEmail, String _cCustId) {
customerName = _cName;
customerPhone = _cPhone;
customerEmail = _cEmail;
customerId = _cCustId;
}
}
you can initialize the adapter,
add the items in Arraylist and show in the list by using
SearchCustomerAdapter boxAdapter;
ArrayList<SearchCustomerItem> products = new ArrayList<SearchCustomerItem>();
to add items in arraylist
products.add(new SearchCustomerItem("CustomerName","PhoneNo","Cust_EmailId","Cust_Id"));
//Add as many items you want
than
boxAdapter = new SearchCustomerAdapter(SearchActivity.this, products);
list.setAdapter(boxAdapter);
This link might help you. link
You should do it step by step.
Extend Base Adapter class by you Custom Adapter class
Override getView and other related methods
set the adapter to list view adapter.
I have 2 xml files, a main file where I have a listView and the other where I am making some customisations to my listView.
The second xml is used on my Custom ArrayAdapter.
In the second xml i have a ImageView which I would like to set to visible at one moment but I am getting the null pointer exception because i am never setting with setCurrentView the second xml file where is my ImageView.
I am trying to do this:
ImageView statusOk=(ImageView)findViewById(R.id.statusOkImage);
statusOk.setVisibility(0);
Could you please tell me how to resolve that?
Thank you.
Edit:
Here is more code:
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:id="#+id/ListView01"
android:layout_height="wrap_content"
android:layout_width="fill_parent"/>
</LinearLayout>
Second xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView
android:id="#+id/statusOkImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/status_ok"
android:visibility="invisible"/>
<TextView android:id="#+id/name"
android:textSize="14sp"
android:textStyle="bold"
android:textColor="#FFFF00"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView android:id="#+id/cityState"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView android:id="#+id/phone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
MainActivity:
public class TestListActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ArrayList<SearchResults> searchResults = GetSearchResults();
final ListView lv1 = (ListView) findViewById(R.id.ListView01);
lv1.setAdapter(new MyCustomBaseAdapter(this, searchResults));
}
private ArrayList<SearchResults> GetSearchResults(){
ArrayList<SearchResults> results = new ArrayList<SearchResults>();
SearchResults sr1 = new SearchResults();
sr1 = new SearchResults();
sr1.setName("Fred Jones");
sr1.setCityState("Las Vegas, NV");
sr1.setPhone("612-555-8214");
results.add(sr1);
return results;
}
}
custom Adapter:
public class MyCustomBaseAdapter extends BaseAdapter {
private static ArrayList<SearchResults> searchArrayList;
private LayoutInflater mInflater;
public MyCustomBaseAdapter(Context context, ArrayList<SearchResults> results) {
searchArrayList = results;
mInflater = LayoutInflater.from(context);
}
public int getCount() {
return searchArrayList.size();
}
public Object getItem(int position) {
return searchArrayList.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.custom_row_view, null);
holder = new ViewHolder();
holder.txtName = (TextView) convertView.findViewById(R.id.name);
holder.txtCityState = (TextView) convertView.findViewById(R.id.cityState);
holder.txtPhone = (TextView) convertView.findViewById(R.id.phone);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
mInflater=(LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
View view=mInflater.inflate(R.layout.custom_row_view, null);
ImageView statusOk=(ImageView)view.findViewById(R.id.imageView1);
statusOk.setVisibility(View.VISIBLE);
holder.txtName.setText(searchArrayList.get(position).getName());
holder.txtCityState.setText(searchArrayList.get(position).getCityState());
holder.txtPhone.setText(searchArrayList.get(position).getPhone());
return convertView;
}
static class ViewHolder {
TextView txtName;
TextView txtCityState;
TextView txtPhone;
}
}
And finnaly the resource class for the listView
public class SearchResults {
private String name = "";
private String cityState = "";
private String phone = "";
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setCityState(String cityState) {
this.cityState = cityState;
}
public String getCityState() {
return cityState;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getPhone() {
return phone;
}
}
To set visibility view defined in xml, you need to inflate that view in activity, setContentView do it automatically, and as you are not invoking setContentView on second xml, then use:
LayoutInflater inflater=(LayoutInflater)getSystemService(Layout_INFLATER_SERVICE);
View view=inflater.inflate(R.layout.secondxml, null);
and then find your view from that view:
ImageView statusOk=(ImageView)view.findViewById(R.id.statusOkImage);
statusOk.setVisibility(0);
but it will work only for view object, it does not affect original xml.
Change to :
statusOk.setVisibility(View.INVISIBLE);
and check is image is ready to use findViewById, like you call the method and after do setContentView or if it really is ImageView, etc.
Here is the solution for accessing the view from another class.
Note : currentActivity is the context of root class
LayoutInflater inflater = (LayoutInflater)currentActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view=inflater.inflate(R.layout.secondxml, null);
Use LayoutInflater.getLayoutInflater() to instantiate layout XML file into its corresponding View objects.
ImageView imgview=(ImageView)findViewById(R.id.imageView1);
imgview.setVisibility(View.INVISIBLE); //for invisibility.
imgview.setVisibility(View.VISIBLE); //make your image visible where ever you want