I have created an application which is a simple form. Users will enter username data and password into each editText pair provided.
My problem comes with extracting this data. Normally, I would extract by the "#id/" value assigned to each editText, but as I am using an adapter and a separate xml file for the row this is not possible, as each editText has the same id.
Does anyone have an idea how I might go about doing this?
Main.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<Button
android:id="#+id/cancelbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/cancel"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:paddingLeft="50dp"
android:paddingRight="50dp"/>
<Button
android:id="#+id/submitbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/submit"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:paddingLeft="50dp"
android:paddingRight="50dp"/>
<ListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/list"
android:layout_alignParentTop="true"
android:layout_above="#id/cancelbutton" />
list.xml : used for individual row
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/logo"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:src="#drawable/g" >
</ImageView>
<EditText
android:id="#+id/firstLine"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="email"
>
</EditText>
<EditText
android:id="#+id/secondLine"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_alignRight="#id/logo"
android:layout_alignParentRight="true"
android:layout_below="#id/firstLine"
android:text="password"
>
</EditText>
public class ColorAdapter extends ArrayAdapter<String> {
private final Context context;
private final String[] values;
public SocialSiteAdapter(Context context, String[] values) {
super(context, R.layout.list, values);
this.context = context;
this.values = values;
}
// GetView does what exactly..?
#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.list, parent, false);
ImageView imageView = (ImageView) rowView.findViewById(R.id.logo);
// Change icon based on name
String s = values[position];
System.out.println(s);
if (s.equals("Blue")) {
imageView.setImageResource(R.drawable.b);
} else if (s.equals("Green")) {
imageView.setImageResource(R.drawable.g);
} else if (s.equals("Red")) {
imageView.setImageResource(R.drawable.r);
} else if (s.equals("Yellow")) {
imageView.setImageResource(R.drawable.y);
} else {
imageView.setImageResource(R.drawable.ic_launcher);
}
return rowView;
}
}
You need to first select the row and then inside the row select the EditTexts by their known #id
To list the entries you could go like:
ListView listView = getListView();
for (int i = 0; i < listView.getCount(); i++) {
Layout row = (Layout) listView.getItemAtPosition(i); /// XXX
EditText t = (EditText) row.findViewById(R.id.firstLine);
// ...
}
You need to check by yourself in the line with XXX what the getItem.. call returns and change accordingly.
Related
I've been dabbling with android here and there for the past few months (mostly just tutorials). I've been working on a texting app (for myself) in my free time to learn, and I've succeeded in getting a different layout for each row, but it doesn't work as I'd intended.
Each row is either going to be left or right (left by default), depending on if the number that's in the cursor's position is my phone number or not.
The problem is that my test data looks like this (where the green is my text):
Here's the code for my custom adapter:
public class ConversationMessageListAdapter extends SimpleCursorAdapter {
private LayoutInflater inflater;
private String myPhoneNumber;
public ConversationMessageListAdapter(Context context, int layout, Cursor cursor, String[] from, int[] to, int flags) {
super(context, layout, cursor, from, to, flags);
myPhoneNumber = getMyPhoneNumber(context);
inflater = LayoutInflater.from(context);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
String number = cursor.getString(2);
System.out.println("phone#: "+number);
System.out.println("my#: "+myPhoneNumber);
if(number.equals(myPhoneNumber)){
View view = inflater.inflate(R.layout.single_message_layout_right, null);
return view;
}
return super.newView(context, cursor, parent);
}
public String getMyPhoneNumber(Context context){
TelephonyManager tMgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
return tMgr.getLine1Number();
}
}
You can see my attempt at debugging the issue by printing out the values of myPhoneNumber and number. It looks like they aren't always matching up correctly with the rows. It'll show the friend's number on the row where it should be mine, yet if I leave the default layout (keep them all to the left) it shows my number on that same row in the textview. Like:
555-555-FRND
Have you played Dynasty Warriors?
555-555-MINE
Not yet. Maybe soon.
But at that point, what get's printed is:
phone#: 555-555-FRND
my# 555-555-MINE
phone#: 555-555-FRND
my# 555-555-MINE
When it should look like:
phone#: 555-555-FRND
my# 555-555-MINE
phone#: 555-555-MINE
my# 555-555-MINE
I'm at a loss for what's causing this.
If it helps, here's my setViewBinder:
textsDbAdapter.setViewBinder(new ConversationMessageListAdapter.ViewBinder() {
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
#Override
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
if(columnIndex == 2){
String number = cursor.getString(columnIndex);
String sentBy = getContactName(contentResolver, number);
if(number.equals(myPhoneNumber)){
return false;
}
TextView sender = (TextView) view;
sender.setText(sentBy);
return true;
}
//datetime
if(columnIndex == 5){
Long messageDatetime = Long.valueOf(cursor.getString(columnIndex));
String receivedOn;
if(startOfToday > messageDatetime){
receivedOn = getDateFromDatetime(messageDatetime);
} else {
receivedOn = getTimeFromDatetime(messageDatetime);
}
TextView datetime = (TextView) view;
datetime.setText(receivedOn);
return true;
}
return false;
}
});
Edit: I've also found out that when I scroll up and then back down, the rows will align randomly.
EDIT2: XML added
single_message_layout_right.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="0dp"
android:paddingRight="5dp"
android:paddingTop="0dp"
android:paddingBottom="0dp"
android:layout_gravity="right"
tools:context=".ConversationActivity">
<!--Datetime Received-->
<TextView
android:id="#+id/datetime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="bottom"
android:layout_below="#+id/messageContent"
android:layout_toLeftOf="#+id/displayPicContainer"
android:textSize="14sp"
android:textColor="#9110828f" />
<!--Message-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/messageContent"
android:textSize="15sp"
android:layout_marginTop="5dp"
android:layout_toLeftOf="#+id/displayPicContainer"/>
<!--Display picture layout-->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:padding="3dp"
android:layout_marginLeft="5dp"
android:id="#+id/displayPicContainer">
<!--Display picture-->
<ImageView
android:layout_width="45dp"
android:layout_height="45dp"
android:src="#drawable/bigboss150x150"
android:id="#+id/displayPic"/>
</LinearLayout>
</RelativeLayout>
single_message_layout_left.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="0dp"
android:paddingRight="5dp"
android:paddingTop="0dp"
android:paddingBottom="0dp"
tools:context=".ConversationActivity">
<!--Display picture layout-->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="3dp"
android:layout_marginRight="5dp"
android:id="#+id/displayPicContainer">
<!--Display picture-->
<ImageView
android:layout_width="45dp"
android:layout_height="45dp"
android:src="#drawable/bigboss150x150"
android:id="#+id/displayPic"/>
</LinearLayout>
<!-- sender -->
<TextView
android:id="#+id/sender"
android:textSize="14sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:text="NAME"
android:textColor="#ff9b9aa0"
android:layout_toRightOf="#+id/displayPicContainer"/>
<!--Datetime Received-->
<TextView
android:id="#+id/datetime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="bottom"
android:layout_below="#+id/messageContent"
android:layout_toRightOf="#+id/displayPicContainer"
android:textSize="14sp"
android:textColor="#9110828f" />
<!--Message-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/messageContent"
android:textSize="15sp"
android:layout_below="#+id/sender"
android:layout_toRightOf="#+id/displayPicContainer"/>
</RelativeLayout>
conversation_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView
android:id="#+id/conversationListView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="43dp"
android:stackFromBottom="true"
android:transcriptMode="normal">
</ListView>
<RelativeLayout
android:id="#+id/form"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:orientation="vertical"
android:background="#ffffff">
<EditText
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:inputType="textCapSentences|textMultiLine"
android:ems="10"
android:lines="5"
android:minLines="1"
android:hint="Enter message"
android:id="#+id/newMessageText"
android:scrollHorizontally="true"
android:scrollbars="vertical"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_toLeftOf="#+id/sendButton"/>
<Button
android:layout_width="60dp"
android:layout_height="wrap_content"
android:text="Send"
android:id="#+id/sendButton"
android:layout_alignBottom="#+id/newMessageText"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
</RelativeLayout>
</RelativeLayout>
I switched from doing newView to getView and this is working for me.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row;
Log.d("RowID", messages.getString(messages.getColumnIndex("_id")));
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
String fromNumber = messages.getString(messages.getColumnIndex("fromNumber"));
if(fromNumber.equals(myPhoneNumber)){
row = inflater.inflate(R.layout.single_message_layout_right, parent, false);
} else {
row = inflater.inflate(R.layout.single_message_layout_left, parent, false);
TextView sender = (TextView) row.findViewById(R.id.sender);
String name = getContactName(fromNumber);
sender.setText(name);
}
TextView datetime = (TextView) row.findViewById(R.id.datetime);
Long messageDatetime = messages.getLong(messages.getColumnIndex("datetime"));
String receivedOn;
if(startOfToday > messageDatetime){
receivedOn = getDateFromDatetime(messageDatetime);
} else {
receivedOn = getTimeFromDatetime(messageDatetime);
}
datetime.setText(receivedOn);
String message = messages.getString(messages.getColumnIndex("message"));
TextView messageContent = (TextView) row.findViewById(R.id.messageContent);
messageContent.setText(message);
return row;
}
I have a list that when you click on the row on the right side the layout with the icon is changed by other. This makes it well but when I scrolling in the list, I notice there are rows with the same icon without do click. Also, if I scroll quickly these same icons are lost and are built differently. I think it's on the reuse of cells but I can not find the solution. What I want is that the image stays active only in the row where clicka.
Thanks!!
Adapter class:
public class ListadoVotantesArrayAdapter extends ArrayAdapter<Votante> {
private Context context;
private LayoutInflater inflater;
private ArrayList<Votante> listaVotantes;
private int rowLayout;
private View mConverView;
public ListadoVotantesArrayAdapter(Context context, int resource, ArrayList<Votante> objects) {
super(context, resource,objects);
this.context = context;
this.inflater = LayoutInflater.from(context);
this.listaVotantes = objects;
this.rowLayout = resource;
}
public int getCount(){
return this.listaVotantes.size();
}
public Votante getVotante(int position){
return this.listaVotantes.get(position);
}
private static class ViewHolder {
public TextView lblName;
public TextView lblLastName;
public TextView lblDni;
public TextView lblVoterNumber;
public RelativeLayout lytVoted;
public RelativeLayout lytCanVote;
public RelativeLayout lytUndo;
}
public View getView(int position, View converView, ViewGroup parent) {
final ViewHolder viewHolder;
mConverView = converView;
if (mConverView == null){
viewHolder = new ViewHolder();
this.mConverView = inflater.inflate(this.rowLayout, parent, false);
if (mConverView != null){
viewHolder.lblName = (TextView) mConverView.findViewById(R.id.lblVoterName);
viewHolder.lblLastName = (TextView) mConverView.findViewById(R.id.lblVoterLastName);
viewHolder.lblDni = (TextView) mConverView.findViewById(R.id.lblDni);
viewHolder.lblVoterNumber = (TextView) mConverView.findViewById(R.id.lblNumber);
viewHolder.lytVoted = (RelativeLayout) mConverView.findViewById(R.id.lytVoted);
viewHolder.lytCanVote = (RelativeLayout) mConverView.findViewById(R.id.lytCanVote);
viewHolder.lytUndo = (RelativeLayout) mConverView.findViewById(R.id.lytUndo);
mConverView.setTag(viewHolder);
}
}else{
viewHolder = (ViewHolder) mConverView.getTag();
}
Votante votante = getVotante(position);
viewHolder.lblName.setText(votante.getNombre());
viewHolder.lblLastName.setText(votante.getApellidos());
viewHolder.lblDni.setText(votante.getDni());
viewHolder.lblVoterNumber.setText(""+votante.getNumVotante());
if (votante.getVotado()){
viewHolder.lytVoted.setVisibility(View.VISIBLE);
viewHolder.lytCanVote.setVisibility(View.GONE);
}else{
viewHolder.lytVoted.setVisibility(View.GONE);
viewHolder.lytCanVote.setVisibility(View.VISIBLE);
}
mConverView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
viewHolder.lytUndo.setVisibility(View.VISIBLE);
notifyDataSetChanged();
}
});
return mConverView;
}
}
Layout Row:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/lyt_voter"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="1dp">
<RelativeLayout
android:id="#+id/lytVoterNumber"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_alignParentLeft="true"
android:background="#color/lightBlueItemList">
<TextView
android:id="#+id/lblNumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="1999"
android:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>
<LinearLayout
android:id="#+id/lytVoterData"
android:layout_width="wrap_content"
android:layout_height="70dp"
android:layout_alignParentTop="true"
android:layout_toLeftOf="#+id/lytCanVote"
android:layout_toRightOf="#+id/lytVoterNumber"
android:layout_toStartOf="#+id/lytCanVote"
android:background="#color/whiteItemList"
android:orientation="vertical"
android:padding="5dp">
<TextView
android:id="#+id/lblVoterLastName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Suarez Garcia de la Serna"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/lblVoterName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="José Carlos"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/lblDni"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="44950962S"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
<RelativeLayout
android:id="#+id/lytCanVote"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_alignParentRight="true"
android:background="#color/yellowItemList"
android:minHeight="30dp"
android:minWidth="30dp">
<ImageView
android:id="#+id/imgVote"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="#drawable/flecha" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/lytVoted"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_alignParentRight="true"
android:background="#color/grrenAcceptList"
android:minHeight="30dp"
android:minWidth="30dp"
android:visibility="gone">
<ImageView
android:id="#+id/imgAccept"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="#drawable/aceptar"
/>
</RelativeLayout>
<RelativeLayout
android:layout_width="70dp"
android:layout_height="70dp"
android:minHeight="30dp"
android:minWidth="30dp"
android:background="#color/redD3"
android:id="#+id/lytUndo"
android:layout_alignParentRight="true"
android:visibility="gone">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imgUndo"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:src="#drawable/undo"/>
</RelativeLayout>
</RelativeLayout>
You need to follow below Idea
1) this line of code mConverView = converView; doesn't makes sense. directly use converView(View from getView param). Remove mConvertView from the adapter.
2) Add some mechanism which can tell you which row is clicked and save that variable.
Example:- Have an boolean Array of size Rows.size . and set them in onClick.
Boolean[] array = new Boolean[getSize()];
in onClick that you already have in your getview set this.
public void onClick(View v) {
array[position] = !array[position];
viewHolder.lytUndo.setVisibility(View.VISIBLE);
//You do not need to call notifyDatasetChange.
3) in getView(), when you are setting data in to row items/or just before onClick. have a check like below.
if(array[position])// this will tell you if you need to show or hid lytUndo thing
viewHolder.lytUndo.setVisibility(View.VISIBLE); // Show it
else
viewHolder.lytUndo.setVisibility(View.GONE); // hide it or do whatever you want
You might need to set some params as final
I have written this as simple as possible, comment back with your result.
Above is the main screen of my app with a custom adapter for listview. How do I put a different icon for each row in the listview? I tried putting an ImageView in the xml but it overwrites my whole screen only showing an icon.
MainAcitivty xml:
<?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:id="#+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/hp_color"
tools:context=".MainActivity" >
<TextView
android:id="#+id/cityText"
style="?android:attr/textAppearanceMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:textSize="28sp" />
<ImageView
android:id="#+id/condIcon"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentLeft="true"
android:layout_below="#id/cityText"
android:contentDescription="weather icon" />
<TextView
android:id="#+id/condDescr"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/condIcon"
android:textSize="20sp" />
<ListView
android:id="#+id/mainListView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" />
<ImageButton
android:id="#+id/btnPicturePage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:onClick="picturePage"
android:src="#drawable/photo" />
Custom adapter:
public class WeatherAdapter extends ArrayAdapter<String> {
private final Activity context;
private ArrayList<String> weatherData;
static class ViewHolder {
public TextView text;
public ImageView image;
}
public WeatherAdapter(Activity context, ArrayList<String> weatherData) {
super(context, R.layout.list, weatherData);
this.context = context;
this.weatherData = weatherData;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
// reuse views
if (rowView == null) {
LayoutInflater inflater = context.getLayoutInflater();
rowView = inflater.inflate(R.layout.list, null);
// configure view holder
ViewHolder viewHolder = new ViewHolder();
viewHolder.text = (TextView) rowView.findViewById(R.id.rowTextView);
rowView.setTag(viewHolder);
}
ViewHolder holder = (ViewHolder) rowView.getTag();
ArrayList<String> s = new ArrayList<String>(weatherData);
String []sa = new String [s.size()];
sa = s.toArray(sa);
holder.text.setText(sa[position]);
if (sa[position].startsWith("Air pressure")) {
rowView.setBackgroundResource(R.color.skyblue) ;
}
return rowView;
}
List xml
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/rowTextView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:textSize="16sp"
android:textColor="#color/white" >
</TextView>
Your list.xml should be something similar to this (taken from one my files)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:gravity="center_vertical" android:orientation="horizontal"
android:background="#drawable/xml_pressed_bg" android:clickable="true" android:layout_width="fill_parent"
android:layout_height="54dip"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:ttshow="http://schemas.android.com/apk/res-auto">
<ImageView android:id="#+id/imgThumb" android:layout_width="42.0dip" android:layout_height="42.0dip" android:scaleType="fitXY"
android:src="#drawable/sample_dj" />
<TextView android:textSize="14.0sp" android:textColor="#ff666666" android:id="#+id/txtName"
android:layout_width="180dip" android:layout_height="wrap_content"
android:singleLine="true" android:shadowColor="#99ffffff" style="#style/TextShadowLight"
android:text="Hello" android:paddingLeft="10dip"/>
</LinearLayout>
Every row item has an image (imgThumb). This needs to be changed or set to a static image, depending on your needs. This is done in the adapters' getView() method.
imgThumb.setImageResource(R.drawable.my_image);
Private TypedArray img;
img=getResource.obtainTypedArray(R.array.imgIcon)
if (sa[position].startsWith("Air pressure")) {
rowView.setBackgroundResource(R.color.skyblue) ;
holder.image.setImageResource(img.gerResourceId[0]);
}else if (sa[position].startsWith("Air Condition")) {
holder.image.setImageResource(img.gerResourceId[1]);
}
My question: Why am I getting an error of java.lang.NullPointerException for trying to set set an adapter to one of my listviews in subListView.setAdapter(adapter2);
I am trying to create an app for learning purposes that will display subjects in a listview and when one of the items/subjects on the listview is clicked a sub item list will appear.
Right now I am just trying to show a listview view with their subitems shown.
Here is my code:
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
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=".MainActivity" >
<TextView
android:id="#+id/textview1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="150dp"
android:layout_alignLeft="#+id/button1"
android:layout_alignRight="#+id/listView1"
android:layout_below="#+id/button1"
android:text="#string/hello_world" />
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/textview1" >
</ListView>
</RelativeLayout>
group_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/groupItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ListView
android:id="#+id/sublistView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/groupItem"
android:layout_marginLeft="26dp" >
</ListView>
</RelativeLayout>
db_items.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:adjustViewBounds="true"
android:maxHeight="60dp"
android:maxWidth="60dp"
android:src="#drawable/ic_launcher" />
<TextView
android:id="#+id/subSubjectTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/imageView1"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_toRightOf="#+id/imageView1"
android:text="Jesus is God"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/subIdtextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="Small Text"
android:visibility="invisible"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="#+id/subScriptTextView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_below="#+id/textView1"
android:text="John 1:1-12"
android:textAppearance="?android:attr/textAppearanceSmall" />
</RelativeLayout>
MainActivity.java
public class MainActivity extends Activity {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
protected void onCreate(Bundle savedInstanceState) {
//Creates DB and Tables if they do not exist... This part works
popList();
}
public void popList(){
ListView listView = (ListView) findViewById(R.id.listView1);
ListView subListView = (ListView) findViewById(R.id.sublistView);
TextView textv = (TextView)findViewById(R.id.textview1);
String topList[] = {"First", "Second", "Third"};
//Queries the DB and stores it in a Cursor... This part works
textv.append(" Cursor Count = " + c.getCount()); //this is for debugging purposes
int iId = c.getColumnIndex("id");
int iSummary = c.getColumnIndex("Summary");
int iScripts = c.getColumnIndex("Scripts");
int iDescription = c.getColumnIndex("Description");
int iSourceType = c.getColumnIndex("SourceType");
cursor.moveToFirst();
for (int j=0; j<c.getCount(); j++)
{
int image = 0;
if(c.getString(iSourceType).equals("Bible"))
{
image = R.drawable.bible;
}
if(c.getString(iSourceType).equals("Article"))
{
image = R.drawable.article;
}
if(c.getString(iSourceType).equals("Video"))
{
image = R.drawable.video;
}
myLVItems.add(new lvItem(c.getString(iId), c.getString(iSummary), c.getString(iScripts), c.getString(iDescription), image));
c.moveToNext();
}
ArrayAdapter<lvItem> adapter2 = new myListAdapter();
textv.append(" subListView Count = " + myLVItems.size()+ " adapter2 Count: " + adapter2.getCount()); //this is for debugging purposes
subListView.setAdapter(adapter2); //this is first error that the logcat points to
for (int i=0; i<topList.length; i++)
{
myGroupTopItems.add(new topgroupItem(topList[i], null));
}
ArrayAdapter<topgroupItem> adapter = new myTopListAdapter();
listView.setAdapter(adapter);
}
private class myListAdapter extends ArrayAdapter<lvItem>{
public myListAdapter(){
super(MainActivity.this, R.layout.db_items, myLVItems);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// make sure we have a view to work with (may have been given null
View itemView = convertView;
if(itemView == null)
{
itemView = getLayoutInflater().inflate(R.layout.db_items, parent, false);
}
//find the item to work with
lvItem currentLVItem = myLVItems.get(position);
//fill the view
ImageView imageView = (ImageView) itemView.findViewById(R.id.imageView1);
imageView.setImageResource(currentLVItem.getIconId());
TextView hiddenView = (TextView) itemView.findViewById(R.id.subIdtextView);
hiddenView.setText(currentLVItem.getId());
TextView summaryView = (TextView) itemView.findViewById(R.id.subSubjectTextView);
summaryView.setText(currentLVItem.getSummary());
TextView descripView = (TextView) itemView.findViewById(R.id.subScriptTextView2);
descripView.setText(currentLVItem.getScripts());
return itemView;
}
}
private class myTopListAdapter extends ArrayAdapter<topgroupItem>{
public myTopListAdapter() {
super(MainActivity.this, R.layout.group_item, myGroupTopItems);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View itemView = convertView;
if(itemView == null)
{
itemView = getLayoutInflater().inflate(R.layout.group_item, parent, false);
}
topgroupItem currentTGItem = myGroupTopItems.get(position);
TextView textView = (TextView) itemView.findViewById(R.id.groupItem);
textView.setText(currentTGItem.getText());
return itemView;
}
}
}
This is what textv displays: Cursir Count = 3 subListView Count = 3 adapter2 Count: 3
I'm not sure why I am getting a Null for subListView. I'm not looking for an expanded listview with what I am doing
Sorry for all the code. Any help would be greatly appreciated
First: you call popList() in onCreate(). That is before the List gets populated with items and therefore there is no child view with the id sublistView.
Second: DO NOT ADD A LIST INTO A LIST ITEM! No ScrollViews inside another ScrollView! You might wanna check out ExpandableListView if you'd like to have sub lists.
I've been trying to figure out what is going on with this for a little while, maybe I have been staring at it too long... I feel like it's something simple.
Here is my ListActivity class
public class ResultsListActivity extends ListActivity {
private ArrayList<Result> results = new ArrayList<Result>();
private ListView list;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sp_history);
//set up list
list = new ListView(this);
}
#Override
protected void onResume()
{
super.onResume();
results = openAndQueryDatabase();
displayResultList();
}
private void displayResultList() {
list.setAdapter(new HistoryArrayAdapter(this.getBaseContext(), results));
}
private ArrayList<Result> openAndQueryDatabase() {
DatabaseHandler dbh = new DatabaseHandler(getBaseContext());
ArrayList<Result> toReturn = dbh.getAllResults();
return toReturn;
}//open and query database
public int getCount() {
return null == results ? 0 : results.size();
}
}
Here is my ListAdapterClass
public class HistoryArrayAdapter extends ArrayAdapter<Result> {
private final Context context;
private final ArrayList<Result> values;
private int layoutId;
public HistoryArrayAdapter(Context context, ArrayList<Result> results) {
super(context, R.layout.history_row, results);
this.context = context;
this.layoutId = R.layout.history_row;
this.values = results;
}
#Override
public int getCount() {
return values.size();// more than zero
}
#Override
public Result getItem(int position) {
return values.get(position);// may be in your case
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView==null)
{
// inflate the layout
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
convertView = inflater.inflate(layoutId, parent, false);
}// if convertView == null
//set up our views
TextView uploadSpeed = (TextView) convertView.findViewById(R.id.upload_speed_history);
TextView downloadSpeed = (TextView) convertView.findViewById(R.id.download_speed_history);
TextView pingTime = (TextView) convertView.findViewById(R.id.ping_history_text);
TextView networkName = (TextView) convertView.findViewById(R.id.history_network_name);
TextView dateTime = (TextView) convertView.findViewById(R.id.history_dateTime);
ImageView imageView = (ImageView) convertView.findViewById(R.id.history_connection);
//set up our values
Result row = values.get(position);
uploadSpeed.setText(row.getUpload());
downloadSpeed.setText(row.getDownload());
pingTime.setText(row.getPingTime());
networkName.setText(row.getNetworkName());
dateTime.setText(row.getDateTime());
if(row.getNetworkType() == "NETWORK_WIFI")
imageView.setImageResource(R.drawable.ico_wifi);
else
imageView.setImageResource(R.drawable.ico_cell);
return convertView;
}//getView
}
Here is the .xml for the ListView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:divider="#b5b5b5"
android:dividerHeight="1dp" />
</LinearLayout>
And Here is the 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="wrap_content"
android:orientation="vertical" >
<RelativeLayout
android:id="#+id/realtive_line_1"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/history_network_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginLeft="26dp"
android:layout_toRightOf="#+id/imageView1"
android:text="TextView" />
<ImageView
android:id="#+id/history_connection"
android:layout_width="20dip"
android:layout_height="20dip"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft = "20dip"
android:layout_marginTop = "5dip"
android:src="#drawable/ico_wifi" />
<TextView
android:id="#+id/history_dateTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="65dp"
android:layout_below="#+id/network_name"
android:text="2013-08-15 12:35:00 PM"
android:textSize="10sp" />
</RelativeLayout>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/realtive_line_1"
>
<ImageView
android:id="#+id/imageView2"
android:layout_width="15dip"
android:layout_height="15dip"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="23dp"
android:layout_marginTop = "15dip"
android:src="#drawable/ico_ping" />
<TextView
android:id="#+id/ping_history_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="25dp"
android:layout_toRightOf="#+id/imageView2"
android:text="30 ms"
android:textSize = "15sp"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ImageView
android:id="#+id/results_icon_up"
android:layout_width="20dip"
android:layout_height="20dip"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:src="#drawable/ico_up"
android:layout_marginRight = "40dip" />
<ImageView
android:id="#+id/results_icon_down"
android:layout_width="20dip"
android:layout_height="20dip"
android:layout_alignParentRight="true"
android:layout_marginTop="5dip"
android:layout_below ="#+id/results_icon_up"
android:src="#drawable/ico_down"
android:layout_marginRight = "40dip" />
<TextView
android:id="#+id/upload_speed_history"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/results_icon_down"
android:layout_marginRight="15dp"
android:layout_toLeftOf="#+id/results_icon_up"
android:text="4.26 Mbps"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="#+id/download_speed_history"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="#+id/upload_speed_history"
android:layout_alignTop="#+id/results_icon_down"
android:text="24.56 Mbps"
android:textAppearance="?android:attr/textAppearanceSmall" />
</RelativeLayout>
<ImageView
android:id="#+id/imageView3"
android:layout_width="20dip"
android:layout_height="20dip"
android:layout_alignParentRight ="true"
android:layout_centerVertical="true"
android:src="#drawable/arrow" />
</RelativeLayout>
Things that I do know... I do have results. I can see it in the debugger and they are populated fine. I know I have a few things that look like unnecessary methods, there is work to be done there to make sure the app isn't in the middle of a process before it populates the list.
Change your onCreate() like below,
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sp_history);
//set up list
list = getListView();
}
AS you've stated that you are using Asynchronous call to get the Database results... even though while debugging you are getting the results, chances are that while actually running, the results might be getting after the adapter has been set in the following line hence the length of results in adapter is 0, so your getView() isn't getting a callback.
Either can have a Custom Listener that will get a call back when the results have been fetched and then you can set the adapter to the listview OR another solution might be to hold the instance of your adapter and then add the acquired results to the adapter using the Adapter.add() method and then call Adapter.notifyDataSetChanged() method.
Edit:- Also as you are using ListActivity, there's no need to create a new ListView instance. Just call getListView() method to obtain the ListView instance as the above answerer suggested.