Custom ListView not populating - java

I've been dealing with this for a few weeks now. I've already seen all other related questions and it does not help. I'm trying to populate a custom ListView and can't for the life of me get it to work. I'll post all the relevant information hoping someone will notice my mistake.
Activity Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".MainActivity"
android:background="#000000">
<ListView
android:id="#+id/deviceListView"
android:layout_width="400px"
android:layout_height="fill_parent"
android:textColor="#ffffff"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"/>
</LinearLayout>
Custom Row layout:
<?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:background="#000000">
<TextView android:id="#+id/textId"
android:textSize="50sp"
android:text="ID"
android:textColor="#FFFFFF"
android:textStyle="bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="vertical">
<TextView android:id="#+id/textTimestamp"
android:textSize="16sp"
android:text="Timestamp"
android:textColor="#FFFFFF"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
android:layout_height="wrap_content"/>
<TextView android:id="#+id/textCoordinates"
android:textSize="16sp"
android:text="Coordinates"
android:textColor="#FFFFFF"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView android:id="#+id/textDistance"
android:textSize="16sp"
android:text="Distance"
android:textColor="#FFFFFF"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
Adapter model:
public class DeviceList {
public static ArrayList<Device> list;
public static void loadModel(int quantity) {
ArrayList<Device> listTmp = new ArrayList<Device>();
for (int i = 0; i < quantity; i++) {
listTmp.add(new Device(System.currentTimeMillis(), i, new float[]{0, 0}, System.currentTimeMillis() / (i + 1)));
}
list = listTmp;
}
public static Device GetById(int id){
Device tmp = null;
for(Device device : list){
if (device.getID() == id){
tmp = device;
}
}
return tmp;
}
}
Adapter:
public class DeviceArrayAdapter extends ArrayAdapter<Device> {
private Context context;
private int rowResourceId;
private String[] ids;
public DeviceArrayAdapter(Context context, int rowResourceId, String[] devices) {
super(context, rowResourceId);
this.context = context;
this.ids = devices;
this.rowResourceId = rowResourceId;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.device_row, parent, false);
TextView idTextview = (TextView) rowView.findViewById(R.id.textId);
TextView timeStampTextview = (TextView) rowView.findViewById(R.id.textTimestamp);
TextView coordinatesTextview = (TextView) rowView.findViewById(R.id.textCoordinates);
TextView distanceTextview = (TextView) rowView.findViewById(R.id.textDistance);
int id = Integer.parseInt(ids[position]);
timeStampTextview.setText(Long.toString(DeviceList.GetById(id).getTimestamp()));
idTextview.setText(DeviceList.GetById(id).getID());
coordinatesTextview.setText(DeviceList.GetById(id).getCoordinates()[0] + "," + DeviceList.GetById(id).getCoordinates()[1]);
distanceTextview.setText(DeviceList.GetById(id).getDistance() + "");
return rowView;
}
}
And finally the Activity's onCreate method:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// setContentView(R.layout.activity_main);
// ArrayList<Device> list = createDummyDeviceList(5);
DeviceList.loadModel(5);
String[] ids = new String[DeviceList.list.size()];
for (int i= 0; i < ids.length; i++){
ids[i] = Integer.toString(i+1);
}
ListView listView = (ListView) findViewById(R.id.deviceListView);
DeviceArrayAdapter adapter = new DeviceArrayAdapter(this, R.layout.device_row, ids);
listView.setAdapter(adapter);
}
Note: I'm sorry to post like this but I'm desperate. I've already debugged it up to the last line and everything is loaded and there are no Exceptions. But it just won't populate.
[EDIT]
Together with the selected answer I also had different numbered arrays and ids. The ids I generated started from 1 and not 0.

You never pass the dataset to the super class. Change
super(context, rowResourceId);
with
super(context, rowResourceId, devices);
this way the getCount of the ArrayAdapter, returns the devices length and the getView would be invoked. Also to avoid waste of memory and better performance, you should inflate the convertView only once.
Edit. The super is expecting an Array or ArrayList of Device objects. Instead your devices in a String array. Your choice should be consistent. You can either change
extends ArrayAdapter<Device>
with
extends ArrayAdapter<String>
or pass as paramter a Device[] as parameter to your custom Adapter. For instance
public DeviceArrayAdapter(Context context, int rowResourceId, Device[] devices) {

Check sources of ArrayAdapter http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.3_r2.1/android/widget/ArrayAdapter.java#ArrayAdapter.getCount%28%29
In your case you should override method getCount().

Related

How do I create an OnClickListener for a button within my list adapter that will allow me to set the visibility for an EditText view

I currently have a listview that contains a button and EditText view. How do I properly implement an OnClickListener in my list adapter so when each button is clicked, the associated EditText within the view is hidden via the setVisibility method.
Based on my current implementation of the OnClickListener in my list adapter, when I click a button to hide the corresponding EditText within the view it hides the very last EditText within the viewport and does not hide the corresponding EditText that it's in the same view as the button. Below is my listview xml file (inspection_single_row.xml), my list adapter (InspectionAdapter.java) and main activity (MainActivity).
inspection_single_row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Was the sink cleaned floors mopped"
android:id="#+id/text_id"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/check_boxes"
android:layout_marginBottom="20dp"
android:gravity="center_horizontal">
<RadioGroup
android:id="#+id/groupRadio"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:orientation="horizontal">
<RadioButton
android:id="#+id/radioComplete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Complete"
android:checked="false"
android:textColor="#color/grey_mid"/>
<RadioButton
android:id="#+id/radioIncomplete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Incomplete"
android:checked="false"
android:textColor="#color/grey_mid"
android:layout_marginLeft="25dp"/>
</RadioGroup>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="click"
android:onClick="clickMe"
android:id="#+id/btn"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="#+id/master_linlayout"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp">
<EditText
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginBottom="20dp"
android:gravity="top"
android:padding="10dp"
android:textSize="14sp"
android:background="#drawable/border2"
android:inputType="textMultiLine"
android:textColor="#color/grey_mid"
android:id="#+id/edit_text"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
InspectionAdapter.java
public class InspectionAdapter extends ArrayAdapter<InspectionObject> {
ArrayList<InspectionObject> arrayList;
Context context;
int Resource;
LayoutInflater layoutInflater;
ProgressHolder holder;
public InspectionAdapter(Context context, int resource, ArrayList<InspectionObject> objects) {
super(context, resource, objects);
this.context = context;
arrayList = objects;
Resource = resource;
layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
private static class ProgressHolder {
public RadioGroup radio_group;
public EditText deficiency_notes;
public TextView inspection_task;
public RadioButton radio_yes;
public RadioButton radio_no;
public LinearLayout master_layout;
public Button my_button;
}
#Override
public View getView(final int position, View convertView, final ViewGroup parent) {
View v = convertView;
holder = new ProgressHolder();
if(v == null)
{
v = layoutInflater.inflate(Resource, null);
holder.radio_group = (RadioGroup)v.findViewById(R.id.groupRadio);
holder.deficiency_notes = (EditText)v.findViewById(R.id.edit_text);
holder.inspection_task = (TextView)v.findViewById(R.id.text_id);
holder.radio_yes = (RadioButton)v.findViewById(R.id.radioComplete);
holder.radio_no = (RadioButton)v.findViewById(R.id.radioIncomplete);
holder.master_layout = (LinearLayout)v.findViewById(R.id.master_linlayout);
holder.my_button = (Button)v.findViewById(R.id.btn);
v.setTag(holder);
}else{
holder = (ProgressHolder)v.getTag();
}
final InspectionObject inspectionObject = arrayList.get(position);
holder.my_button.setTag(position);
holder.deficiency_notes.setTag(position);
holder.my_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int pos = (Integer) v.getTag(); //the real and updated position
Log.i("ConfirmAdapter","Button # position : " + pos);
Log.i("ConfirmAdapter","EditText # position : " + holder.deficiency_notes.getTag());
}
});
return v;
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
ListView lv;
InspectionAdapter inspection_adapter;
ArrayList<InspectionObject> inspectionList;
Boolean eval;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = findViewById(R.id.listView2);
inspectionList = new ArrayList<InspectionObject>();
inspectionList = new ArrayList<InspectionObject>();
inspectionList.add(new InspectionObject(true, "", "Were the floor mopped?"));
inspectionList.add(new InspectionObject(true, "", "Were the mirrors cleaned?"));
inspectionList.add(new InspectionObject(false, "", "Were the toilets cleaned?"));
inspectionList.add(new InspectionObject(true, "", "Was high/low dusting performed?"));
inspection_adapter = new InspectionAdapter(getApplicationContext(), R.layout.inspection_single_row, inspectionList);
lv.setAdapter(inspection_adapter);
}
}
Edit:
In this part
Log.i("ConfirmAdapter","EditText # position : " + holder.deficiency_notes.getTag())
you are still referencing the holder variable that is created last. As i said before: In getView, for every view, you create a new ProgressHolder assigning it to holder variable. So holder is overwritten everytime getView is called. That's why, Log.i gives your last item.
Try the following:
Put the new ProgressHolder inside if clause.
if(v == null)
{
holder = new ProgressHolder();
This way it only creates a new instance, when the view is null.
Instead of setting the tag for the button to position you can set it to holder like this
holder.my_button.setTag(holder);
you don't need to set tag for EditText.
Then in the onClick you get the corresponding instance of ProgressHolder via getTag() and change the visibilty like this:
holder.my_button.setTag(holder);
holder.my_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ProgressHolder clickedHolder = (ProgressHolder)view.getTag();
clickedHolder.deficiency_notes.setVisibility(View.GONE);
}
});

ListViewAdapter context on fragment activity error, what should I do?

Good night android masters. Please help me. maybe those of you who understand better than me can help me solve the problem I'm facing right now.
1 https://imgur.com/S2TU08q
I made a listview on the fragment. I stopped because I was confused how I proceeded. maybe the code below can help you solve my problem!
This is the fragment I made. I name it Frag_Tour.java
public class Frag_Tour extends Fragment {
ListView listView;
ListViewAdapterTour adapter;
String[] judul1;
String[] judul2;
String[] durasi;
String[] harga;
int[] gambarTour;
ArrayList<Model> arrayList = new ArrayList<Model>();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.frag_tour, container, false);
judul1 = new String[]{"Paket Hemat", "Paket Reguler", "Paket Honeymoon"};
judul2 = new String[]{"Wisata Belitung", "Wisata Belitung", "Wisata Belitung"};
durasi = new String[]{"3 Hari 2 Malam", "4 Hari 3 Malam", "3 Hari 1 Malam"};
harga = new String[]{"Rp 750.000/pax", "Rp 750.000/pax", "Rp 750.000/pax"};
gambarTour = new int[]{
R.drawable.mercusuar_1, R.drawable.mercusuar_2, R.drawable.mercusuar_3
};
listView = rootView.findViewById(R.id.listView);
for (int i = 0; i < judul1.length; i++) {
Model model = new Model(judul1[i], judul2[i], durasi[i], harga[i], gambarTour[i]);
arrayList.add(model);
}
adapter = new ListViewAdapterTour(this, arrayList);
listView.setAdapter((ListAdapter) arrayList);
return rootView;
}
}
this is the xml file. frag_tour.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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:id="#+id/parent_view"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
[2] https://imgur.com/ehPanZM
this is the ListViewAdapter that I have created. I named it ListViewAdapterTour.java
public class ListViewAdapterTour extends BaseAdapter {
Context mContext;
LayoutInflater inflater;
List<Model> modellist;
ArrayList<Model> arrayList;
public ListViewAdapterTour (Context context, List<Model> modellist) {
mContext = context;
this.modellist = modellist;
inflater = LayoutInflater.from(mContext);
this.arrayList = new ArrayList<Model>();
this.arrayList.addAll(modellist);
}
public class ViewHolder {
TextView Judul1, Judul2, Durasi, Harga;
ImageView GambarTour;
}
#Override
public int getCount() {
return modellist.size();
}
#Override
public Object getItem(int i) {
return modellist.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(final int position, View view, ViewGroup parent) {
ViewHolder holder;
if (view==null){
holder = new ViewHolder();
view = inflater.inflate(R.layout.row_tour, null);
holder.Judul1 = view.findViewById(R.id.judul1);
holder.Judul2 = view.findViewById(R.id.judul2);
holder.Durasi = view.findViewById(R.id.durasi);
holder.Harga = view.findViewById(R.id.harga);
holder.GambarTour = view.findViewById(R.id.GambarTour);
view.setTag(holder);
}
else {
holder = (ViewHolder)view.getTag();
}
holder.Judul1.setText(modellist.get(position).getJudul1());
holder.Judul2.setText(modellist.get(position).getJudul2());
holder.Durasi.setText(modellist.get(position).getDurasi());
holder.Harga.setText(modellist.get(position).getHarga());
holder.GambarTour.setImageResource(modellist.get(position).getGambartour());
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (modellist.get(position).getJudul1().equals("Paket Hemat 3 Hari 2 Malam")){
Intent intent = new Intent(mContext, TourDetail.class);
intent.putExtra("contentTv","PAKET HEMAT");
mContext.startActivity(intent);
}
}
});
return view;
}
}
and this is the xml file. row_tour.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:focusableInTouchMode="true"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_margin="#dimen/spacing_middle"
android:layout_weight="1"
app:cardCornerRadius="2dp"
app:cardElevation="2dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="170dp"
android:orientation="vertical">
<ImageView
android:id="#+id/GambarTour"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:src="#drawable/mercusuar_1"
tools:ignore="ContentDescription" />
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/overlay_dark_20" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignTop="#id/GambarTour"
android:layout_margin="#dimen/spacing_medium"
android:orientation="vertical"
tools:ignore="UselessParent">
<TextView
android:id="#+id/judul1"
style="#style/TextAppearance.AppCompat.Large"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Paket Hemat"
android:textColor="#color/White"
android:textStyle="bold" />
<TextView
android:id="#+id/judul2"
style="#style/TextAppearance.AppCompat.Large"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Wisata Belitung"
android:textColor="#color/White"
android:textStyle="bold" />
<TextView
android:id="#+id/durasi"
style="#style/TextAppearance.AppCompat.Caption"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="#string/_3_hari_2_malam"
android:textColor="#color/White" />
</LinearLayout>
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignEnd="#id/GambarTour"
android:layout_alignRight="#id/GambarTour"
android:layout_margin="#dimen/spacing_medium"
android:src="#drawable/ic_favorite_border"
android:tint="#color/White" />
<TextView
android:id="#+id/harga"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignEnd="#id/GambarTour"
android:layout_alignRight="#id/GambarTour"
android:layout_alignBottom="#id/GambarTour"
android:layout_margin="#dimen/spacing_large"
android:background="#drawable/gradient_green"
android:padding="#dimen/spacing_xmedium"
android:text="Rp 750.000/pax"
android:textColor="#color/White" />
</RelativeLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
[3] https://imgur.com/h7WiBgK
and this is the code for the model.java that I use
package com.androidrion.sejengkalapp;
class Model {
private String judul1;
private String judul2;
private String durasi;
private String harga;
private int gambartour;
//constructor
Model(String judul1, String judul2, String durasi, String harga, int gambartour) {
this.judul1 = judul1;
this.judul2 = judul2;
this.durasi = durasi;
this.harga = harga;
this.gambartour = gambartour;
}
//getters
String getJudul1() {
return this.judul1;
}
String getJudul2() {
return this.judul2;
}
String getDurasi() {
return this.durasi;
}
String getHarga() {
return this.harga;
}
int getGambartour() {
return this.gambartour;
}
}
I hope the teachers and masters about Android can help me in solving this problem. what I want is row_tour.xml which I have designed to be listview in frag_tour.xml
[4] https://imgur.com/VLzOUiK
The context should be the activity holding the fragment. So instead of this in your adapter constructor, use getActivity()
adapter = new ListViewAdapterTour(getActivity(), arrayList);

getView() never called on custom adapter

I am aware that other people have asked this question, but I have looked at other solutions and still can't get it to work.
Adapter code:
private class CustomTextAndImageAdapter extends ArrayAdapter<String> {
private Context context;
private Activity activity;
private ArrayList<String> timeArrayList;
private ArrayList<Bitmap> weatherIconArrayList;
private ArrayList<String> descriptionArrayList;
private ArrayList<String> tempArrayList;
private ArrayList<String> popArrayList;
private ArrayList<String> windSpeedArrayList;
public final void setTimeArrayList(ArrayList<String> timeArrayList)
{
this.timeArrayList = timeArrayList;
}
public final void setDescriptionArrayList(ArrayList<String> descriptionArrayList)
{
this.descriptionArrayList = descriptionArrayList;
}
public final void setTempArrayList(ArrayList<String> tempArrayList)
{
this.tempArrayList = tempArrayList;
}
public final void setPopArrayList(ArrayList<String> popArrayList)
{
this.popArrayList = popArrayList;
}
public final void setWindSpeedArrayList(ArrayList<String> windSpeedArrayList)
{
this.windSpeedArrayList = windSpeedArrayList;
}
public final void setWeatherIconArrayList(ArrayList<Bitmap> weatherIconArrayList)
{
this.weatherIconArrayList = weatherIconArrayList;
}
public CustomTextAndImageAdapter(Context context, Activity activity, int resource)
{
super(context, resource);
this.context = context;
this.activity = activity;
}
#Override
public View getView(int position, View view, ViewGroup parent)
{
Log.d(Constants.LOG_TAG, "getView() method called");
LayoutInflater inflater = activity.getLayoutInflater();
View rowView= inflater.inflate(R.layout.itemlistrow, null, false);
TextView timeTextView = (TextView)rowView.findViewById(R.id.time);
timeTextView.setText(timeArrayList.get(position));
Log.d(Constants.LOG_TAG, "Time text view text = " + timeArrayList.get(position));
ImageView iconImageView = (ImageView) rowView.findViewById(R.id.weatherIcon);
iconImageView.setImageBitmap(weatherIconArrayList.get(position));
TextView descriptionTextView = (TextView)rowView.findViewById(R.id.description);
descriptionTextView.setText(descriptionArrayList.get(position));
TextView tempTextView = (TextView)rowView.findViewById(R.id.temp);
tempTextView.setText(tempArrayList.get(position));
TextView popTextView = (TextView)rowView.findViewById(R.id.pop);
popTextView.setText(popArrayList.get(position));
TextView windSpeedTextView = (TextView)rowView.findViewById(R.id.windSpeed);
windSpeedTextView.setText(windSpeedArrayList.get(position));
return rowView;
}
}
List item layout (itemlistrow.xml):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="1">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/time" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/weatherIcon"
/>
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Sunny"
android:id="#+id/description"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="11 C"
android:id="#+id/temp"
/>
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text = "Rain:"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text = "Wind:"
/>
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id = "#+id/pop"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text = "#+id/windSpeed"
/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
In some of the other solutions, it mentions overriding getCount(). Is this what I am doing wrong? If so, how would I know what to put in for getCount(), as there are multiple different ArrayLists used. Is it a case of picking one of them, as they are all the same length, e.g. timeArrayList.size()?
Using multiple ArrayList objects like that kind of defeats the purpose of using an ArrayAdapter, whose idea is to have a single source of items. Not to mention that the code right now doesn't look nice at all.
I'd suggest to first create a Weather object that will hold your data:
public class Weather {
private String time;
private Bitmap weatherIcon;
private String description;
private String temp;
private String pop;
private String windSpeed;
// build object here, provide getters, etc....
.....
}
Than your adapter can be transformed to something simpler like this:
private class CustomTextAndImageAdapter extends ArrayAdapter<Weather>
{
private LayoutInflater inflater;
public CustomTextAndImageAdapter(Context context, Activity activity, int resource, List<Weather> items)
{
super(context, resource, items);
this.inflater = LayoutInflater.from(context);
}
#Override
public View getView(int position, View view, ViewGroup parent)
{
View rowView= inflater.inflate(R.layout.itemlistrow, null, false);
TextView timeTextView = (TextView)rowView.findViewById(R.id.time);
timeTextView.setText(getItem(position).getTime());
ImageView iconImageView = (ImageView) rowView.findViewById(R.id.weatherIcon);
iconImageView.setImageBitmap(getItem(position).getWeatherIcon());
........
return rowView;
}
}
Main difference is that it's now an ArrayAdapter<Weather> and that you're passing the arguments directly in the constructor of the adapter. Users of the adapter now have to call just 1 constructor, instead of all the final methods that had to be called before.
The other major difference is that you're passing the items list to the super class. Now your adapter knows it's size (internally getCount() will be == items.size()) so getView() will be called appropriately.
As a final thought - the adapter is still not using the ViewHolder pattern, which you should totally implement! There's been numerous posts for it, so just search a bit and you'll find it.
This is not a good way to populate a ListView using an adapter which populates the data from multiple ArrayList. Generally we use a single source of dataset to be passed to an adapter in case of showing a list in Android.
So in your case, when you'll call the notifyDatasetChanged it shouldn't take effect in the list properly as far as I can guess.
notifyDatasetChanged basically calls the getCount function of the adapter and checks if the size of the ArrayList associated with the adapter is changed or not. If the size of the ArrayList is changed, it refreshes the ListView and the getView function gets called.
In your case, I don't see any getCount function though. getCount usually returns the size of the ArrayList associated with the adapter.
So I would suggest, using a single ArrayList to be passed to the adapter. You can merge multiple ArrayList and can use one joined HashMap in your case too. Its your decision, exactly how you can pass a single list of your dataset to the adapter to populate them into a ListView.

Custom listview don't work

I'm trying to make a custom listview. I'm not getting error and data are correctly added to my ArrayList but I see nothing on screen. Is there a problem with a layout or the adapter ?
Here is my list row layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/nomtv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"/>
<TextView
android:id="#+id/desctv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/debuttv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/nomtv"
android:layout_toEndOf="#+id/nomtv"/>
<TextView
android:id="#+id/fintv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/desctv"
android:layout_toEndOf="#+id/desctv"/>
</RelativeLayout>
Here is my custom adapter:
public class ListTacheAdapter extends ArrayAdapter<String> {
ArrayList<Tache> taches;
ListView listView = null;
final Context context;
View rowView = null;
TextView nom = null, desc = null, debut = null, fin = null;
public ListTacheAdapter(Context context, ArrayList<Tache> taches) {
super(context, R.layout.row_tache);
// TODO Auto-generated constructor stub
this.context = context;
this.taches = taches;
}
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(R.layout.row_tache, parent, true);
nom = (TextView) rowView.findViewById(R.id.nomtv);
desc = (TextView) rowView.findViewById(R.id.desctv);
debut = (TextView) rowView.findViewById(R.id.debuttv);
fin = (TextView) rowView.findViewById(R.id.fintv);
nom.setText(taches.get(position).getNom());
desc.setText(taches.get(position).getDescription());
debut.setText(taches.get(position).getDebut());
fin.setText(taches.get(position).getFin());
return rowView;
}
}
My activity layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.testapp.ShowActivity" >
<ListView
android:id="#+id/list"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#D46A6A"
android:dividerHeight="1dp"/>
</RelativeLayout>
And my activity class:
public class ShowActivity extends Activity {
ArrayList<Tache> taches;
ListView listView;
TacheDAO td = new TacheDAO(this);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show);
td.open();
taches = td.getAllTache();
td.close();
ListTacheAdapter lta = new ListTacheAdapter(this, taches);
listView = (ListView) findViewById(R.id.list);
listView.setAdapter(lta);
}
}
I'm also a beginner, so i tell what i'd try:
I believe that the problem is in the calling to super() on the onCreate method of the adapter. Try passing super(context, -1) insted of super(context, R.layout.row_tache).
Let me know.

how can i change fontcolor and font type of my listview

I have one activity that contains text view, buttons, spinner and list view
my main XML file contains :
<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="#ffff00"
tools:context="com.example.taxitabriz.MainActivity"
tools:ignore="MergeRootFrame" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="8dp"
android:text="#string/app_name"
android:textSize="35dp"
android:textStyle="bold"
android:textColor="#996600"
android:textAppearance="?android:attr/textAppearanceLarge" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:id="#+id/linearlayout1" >
<Button
android:id="#+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textColor="#996600"
android:text="#string/exit"
android:background="#drawable/backbutton" />
<Button
android:id="#+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textColor="#996600"
android:text="#string/about"
android:background="#drawable/backbutton" />
</LinearLayout>
<Spinner
android:id="#+id/spinner1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="#+id/textView1"
android:layout_marginTop="19dp" />
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/spinner1"
android:layout_above="#+id/linearlayout1"
android:layout_alignParentRight="true"
android:layout_weight="49.94" >
</ListView>
and part of my java code is here:
ArrayAdapter<String> ard=new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line,s1);
sp.setAdapter(ard);
lv1=(ListView) findViewById(R.id.listView1);
ArrayAdapter<String> ard1=new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line,s1);
lv1.setAdapter(ard1);
but i can't change font color or font type in list view or spinner. how can i do it?
You need to create a CustomListAdapter.
private class CustomListAdapter extends ArrayAdapter {
private Context mContext;
private int id;
private List <String>items ;
public CustomListAdapter(Context context, int textViewResourceId , List<String> list )
{
super(context, textViewResourceId, list);
mContext = context;
id = textViewResourceId;
items = list ;
}
#Override
public View getView(int position, View v, ViewGroup parent)
{
View mView = v ;
if(mView == null){
LayoutInflater vi = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mView = vi.inflate(id, null);
}
TextView text = (TextView) mView.findViewById(R.id.textView);
if(items.get(position) != null )
{
text.setTextColor(Color.WHITE);
text.setText(items.get(position));
text.setBackgroundColor(Color.RED);
int color = Color.argb( 200, 255, 64, 64 );
text.setBackgroundColor( color );
}
return mView;
}
}
The list item looks like this (custom_list.xml):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/textView"
android:textSize="20px" android:paddingTop="10dip" android:paddingBottom="10dip"/>
</LinearLayout>
Use the TextView api's to decorate your text to your liking
and you will be using it like this
listAdapter = new CustomListAdapter(YourActivity.this , R.layout.custom_list , mList);
mListView.setAdapter(listAdapter);
If you really want to use androids simple list layout, we see that they declare their textview's identifier as such:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/text1"
style="?android:attr/dropDownItemStyle"
android:textAppearance="?android:attr/textAppearanceLargeInverse"
android:singleLine="true"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:ellipsize="marquee" />
So just make your custom adapter, inflate their layout & find that text view's id. Something like the following:
public final class CustomAdapter extends ArrayAdapter<String> {
private Context context;
ViewHolder holder;
private ArrayList<String> messages;
public CustomAdapter(Context context, ArrayList<String> data) {
this.context = context;
this.messages = data;
Log.d("ChatAdapter", "called constructor");
}
public int getCount() {
return messages.size();
}
public View getView(int position, View convertView, ViewGroup viewGroup) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.simple_dropdown_item_1line, null);
holder = new ViewHolder();
holder.message = (TextView) convertView
.findViewById(R.id.text1);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.message.setText(data.get(position));
holder.message.setTextColor(Color.BLUE);
// don't do this, remember the face variable once just showing explicitly for u
Typeface face=Typeface.createFromAsset(getAssets(), "fonts/HandmadeTypewriter.ttf");
holder.message.setTypeface(face);
return convertView;
}
public static class ViewHolder {
public TextView message;
}
}
Edit: The following is how you would use the custom array adapter in your activity.
// I'm not sure if your sp or lv1 wants the adapter, but
// whatever you require your list view's data to be just
// set the custom adapter to it
CustomAdapter<String> myAdapter = new ArrayAdapter<String>(this, s1);
lv1=(ListView) findViewById(R.id.listView1)
lv1.setAdapter(myAdapter);
You can do like this, add a ListView item in xml,at res/layout/list_item1.xml:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/text1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#0000ff"
android:testStyle="italic"
android:gravity="center_vertical"
android:paddingLeft="6dip"
android:minHeight="?android:attr/listPreferredItemHeight"
/>
then,
ArrayAdapter<String> ard=new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line,s1);
sp.setAdapter(ard);
lv1=(ListView) findViewById(R.id.listView1);
ArrayAdapter<String> ard1=new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line,s1);// **change R.layout.list_item1**
lv1.setAdapter(ard1);
You have to put the .ttf file of font(which you want to add ) in asstes/fonts/ folder and write code in onCreate method like below. i have puted Chalkduster.ttf in my asstes/fonts/ folder
TextView txttest = (TextView) findViewById(R.id.txttest);
Typeface custom_font = Typeface.createFromAsset(getAssets(),
"fonts/Chalkduster.ttf");
txttest.setTypeface(custom_font);
You can handle clicks of selected item by write code just like below
ListView lvNews = (ListView) findViewById(R.id.lvNews);
lvNews.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int position, long arg3) {
// Write your code here
//int newsId = newsArray.get(position).getId();
//Intent i = new Intent(NewsListActivity.this,
// NewsDetailActivity.class);
//i.putExtra(Constants.NEWS_ID, newsId);
//i.putExtra("isFromNotification", false);
//startActivity(i);
}
});

Categories