In the following code I intend to produce both an ouput on the item line and the subitem line but the code is just bringing me up an empty listview. How can I rectify this?
The game is a multiplication times tables game with the intention that when the user enters answers (on prev activity) the answer they entered are shown in the item (i.e. 12 items) and the correct answer for each is shown in each sub-item.
.Java code:
public class Results extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.results);
ListView itemList = (ListView) findViewById(R.id.lvresults);
//gets array from prev act
int[] results = getIntent().getIntArrayExtra("results");
int numberPassed = getIntent().getIntExtra("numberPassed", 0);
ArrayList < HashMap <String, String> > list = new ArrayList < HashMap <String, String> > ();
// loop to give list view
for (int i = 1; i <= 12; ++i)
{
int userAnswer = results[i - 1];
int expectedAnswer = numberPassed * i;
String userString = numberPassed + "x" + i + "=" + userAnswer;
String expectedString = "" + expectedAnswer;
HashMap <String, String> map = new HashMap <String, String> ();
map.put("user", userString);
map.put("expected", expectedString);
list.add(map);
}
String[] keys = {"user", "expected"};
int[] ids = {R.id.user_answer, R.id.expected_answer};
SimpleAdapter adapter = new SimpleAdapter(this, list, android.R.layout.simple_list_item_2, keys, ids);
itemList.setAdapter(adapter);
}
}
XML code:
<?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" >
<ListView
android:id="#+id/lvresults"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</ListView>
<TextView
android:id="#+id/user_answer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15dp" />
<TextView
android:id="#+id/expected_answer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15dp" />
</LinearLayout>
int[] ids={android.R.id.text1,android.R.id.text2}
and remove the two TextView from the layout
Related
I am trying to display list of users from an online database
id username
1 aaaaa
2 bbbbb
3 ccccc
I'm getting the above result, now I want to add another column/TextView besides those username, perhaps firstname, or lastname,
id username lastname
1 aaaaa please
2 bbbbb help
3 ccccc me
I believe this part of the code populates the ListView
private void showEmployee(){
JSONObject jsonObject = null;
ArrayList<HashMap<String,String>> list = new ArrayList<HashMap<String, String>>();
try {
jsonObject = new JSONObject(JSON_STRING);
JSONArray result = jsonObject.getJSONArray(Config.TAG_JSON_ARRAY);
for(int i = 0; i<result.length(); i++){
JSONObject jo = result.getJSONObject(i);
String id = jo.getString(Config.TAG_ID);
String username = jo.getString(Config.TAG_UNAME);
//String firstname = jo.getString(Config.TAG_FNAME);
HashMap<String,String> employees = new HashMap<>();
employees.put(Config.TAG_ID,id);
employees.put(Config.TAG_UNAME,username);
// employees.put(Config.TAG_UNAME,username);
list.add(employees);
}
} catch (JSONException e) {
e.printStackTrace();
}
ListAdapter adapter = new SimpleAdapter(
act_viewAllusers.this, list, R.layout.list_item,
new String[]{Config.TAG_ID,Config.TAG_UNAME},
new int[]{R.id.id, R.id.username});
/*** ListAdapter adapter = new SimpleAdapter(
act_viewAllusers.this, list, R.layout.list_item,
new String[]{Config.TAG_ID,Config.TAG_UNAME,Config.TAG_FNAME},
new int[]{R.id.id, R.id.username,R.id.fname}); ***/
listView.setAdapter(adapter);
}
I have a separate Java class named Config.java which contains some URLs and JSON tags which currently I can't really understand.
Here's some part of it
//JSON Tags
public static final String TAG_JSON_ARRAY="result";
public static final String TAG_ID = "id";
public static final String TAG_UNAME = "username";
public static final String TAG_PWORD = "password";
public static final String TAG_FNAME = "firstname";
public static final String TAG_LNAME = "lastname";
public static final String TAG_BDAY = "birthday";
public static final String TAG_GENDER = "gender";
Here's the XML for my ListView
<?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_marginRight="10dp"
android:id="#+id/id"
android:layout_width="40dp"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/username"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/fname"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/lname"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Another XML file for the ListView
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_act_view_allusers"
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.bayona.lesson1.act_viewAllusers">
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/listView" />
</LinearLayout>
Perhaps it's imposible to add another column or TextView; it's fine, but what bothers me is that I can't change the username displays.
For instance, I want to display lastname besides the id number
LinearLayout provides an android:weightSum attribute. You can set this to 4 to get even column distribution. Each TextView can be given a android:layout_weight and a android:width="0dp" in that case to fill the weight of the column.
Or you can use a GridLayout and put 4 cells in one row.
Or you can use a TableRow.
Point being, you have options. However, you shouldn't think of a ListView as a "spreadsheet". You can make each "row" as complex as you want.
Personally, maybe something like this in each row.
ID Username
Lastname, FirstName
Or don't even show the id and add # before the username...
Firstname Lastname
#Username
Just use the XML editor to create whatever layout you want.
As far as the Java code is concerned. You only have two values being set.
ListAdapter adapter = new SimpleAdapter(
act_viewAllusers.this,
list, // data
R.layout.list_item, // layout
new String[]{Config.TAG_ID,Config.TAG_UNAME}, // from[]
new int[]{R.id.id, R.id.username}); // to[]
So, you add more strings into the from array which are set into the XML id's in the to array from that layout.
Try Like This
ListAdapter adapter = new SimpleAdapter(
act_viewAllusers.this, list, R.layout.list_item,
new String[]{Config.TAG_ID,Config.TAG_UNAME,
Config.NextTAg,Config.NextTag2},
new int[]{R.id.id, R.id.username,R.id.id1,R.id.id2});
Check this if not done
try {
jsonObject = new JSONObject(JSON_STRING);
JSONArray result = jsonObject.getJSONArray(Config.TAG_JSON_ARRAY);
for(int i = 0; i<result.length(); i++){
JSONObject jo = result.getJSONObject(i);
String id = jo.getString(Config.TAG_ID);
String username = jo.getString(Config.TAG_UNAME);
//-----------------
String varName=jo.getString(Config.REQ_TAG);
//-------------
//String firstname = jo.getString(Config.TAG_FNAME);
HashMap<String,String> employees = new HashMap<>();
employees.put(Config.TAG_ID,id);
employees.put(Config.TAG_UNAME,username);
//--------------
employees.put(Config.REQ_TAG,varName);
//-----------
// employees.put(Config.TAG_UNAME,username);
list.add(employees);
}
I have a horizontal Listview. It works fine. My ArrayList eList will show a ListView going across the screen. That's great. My problem is that eList has multiple rows meaning eList might be planes, cars, and boats, or an infinite number of objects. Currently this Horizontal ListView will show only all the kinds of planes OR cars OR boats in the Database. How do show multiple or an infinite number of hListViews going down the screen vertically based upon how many object types(planes,cars,boats,tacos,people).
IN ACTIVITY
HorizontalListView hListView = (HorizontalListView) findViewById(R.id.hlistview1);
hListView.setAdapter(new ItemAdapter());
ArrayList<HashMap<String, String>> eList = controller.getAllts();
ListAdapter adapter = new SimpleAdapter(Su.this,eList,R.layout.view_m_ts, images, ins);
hListView.setAdapter(adapter);
IN DATABASE
public ArrayList<HashMap<String, String>> getAllts() {
ArrayList<HashMap<String, String>> List3;
List3 = new ArrayList<HashMap<String, String>>();
String selectQuery3 = "SELECT DISTINCT * FROM INV where p2 IS NOT NULL ORDER BY p2 COLLATE NOCASE ASC";
SQLiteDatabase database = this.getWritableDatabase();
Cursor cursor3 = database.rawQuery(selectQuery3, null);
HashMap<String, String> map = new HashMap<String, String>();
if (cursor3.moveToFirst()) {
do {
map.put("iImageL", cursor3.getString(13));
map.put("p2", cursor3.getString(2));
map.put("se2", cursor3.getString(10));
map.put("te", cursor3.getString(17));
List3.add(map);
} while (cursor3.moveToNext());
}
close();
return List3;
}
IN XML
<LinearLayout
android:id="#+id/LinearViewa"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight=".1"
android:orientation="vertical" >
<com.devsmart.android.ui.HorizontalListView
android:id="#+id/hlistview1"
android:layout_width="fill_parent"
android:layout_height="10dp"
android:layout_weight=".1"
android:background="#000000" />
</LinearLayout>
I'm going to assume that all objects of different types are in one SQLite table, with the type stored in one of the columns as a string, and you don't have a different table for each type.
Change your getAllts() function to return a HashMap of ArrayLists of HashMaps instead of an ArrayList of HashMaps, so that you can create multiple HorizontalListViews, one for each ArrayList of HashMaps, each one for a particular type. As you iterate through the rows returned in the cursor, get the type and check if there is already an ArrayList for it in your big HashMap, if not then create one and if so then add to the existing one:
public HashMap<String, ArrayList<HashMap<String, String>>> getAllts() {
HashMap<String, ArrayList<HashMap<String, String>>> hashMap = new HashMap<String, ArrayList<HashMap<String, String>>>();
String selectQuery3 = "SELECT DISTINCT * FROM INV where p2 IS NOT NULL ORDER BY p2 COLLATE NOCASE ASC";
SQLiteDatabase database = this.getWritableDatabase();
Cursor cursor3 = database.rawQuery(selectQuery3, null);
int typeColumnIndex = 18; // <- You need to set the correct column here, possibly using cursor3.getColumnIndexOrThrow()
if (cursor3.moveToFirst()) {
do {
// create this HashMap inside the loop because we need a new one each time:
HashMap<String, String> map = new HashMap<String, String>();
ArrayList<HashMap<String, String>> List3;
// get the type of this entry as a string
String typename = cursor3.getString(typeColumnIndex);
// check if there already is an ArrayList for this type:
if(hashMap.containsKey(typename))
{
// get existing ArrayList for this type:
List3 = hashMap.get(typename);
}
else
{
// create new ArrayList for this type:
List3 = new ArrayList<HashMap<String, String>>();
hashMap.put(typename, List3);
}
map.put("iImageL", cursor3.getString(13));
map.put("p2", cursor3.getString(2));
map.put("se2", cursor3.getString(10));
map.put("te", cursor3.getString(17));
List3.add(map);
} while (cursor3.moveToNext());
}
close();
return hashMap;
}
Change your XML so that you have an empty LinearLayout in your activity XML:
<LinearLayout
android:id="#+id/LinearViewa"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight=".1"
android:orientation="vertical" >
</LinearLayout>
and create a separate XML for the horizontal list view that you can create multiple times and add to your LinearLayout dynamically, in horiz_listview.xml or something like that. You can set up your own custom layout with the type name as a TextView header etc:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<!-- Add type name here if you like-->
<com.devsmart.android.ui.HorizontalListView
android:id="#+id/hlistview1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#000000" />
</LinearLayout>
Then in your activity, get the massive hash map containing all the ArrayLists and iterate through it creating a HorizontalListView for each one and add it to the LinearLayout:
LinearLayout layout = (LinearLayout)findViewById(R.id.LinearViewa);
HashMap<String, ArrayList<HashMap<String, String>>> eHash = controller.getAllts();
LayoutInflater inflater = getLayoutInflater();
for(Map.Entry<String, ArrayList<HashMap<String, String>>> entry : eHash.entrySet())
{
// get the type name and ArrayList of Hashmaps for this type:
String typename = entry.getKey();
ArrayList<HashMap<String, String>> eList = entry.getValue();
// inflate a horizonal list view and add it to the layout:
View view = inflater.inflate(R.layout.horiz_listview, null, false);
layout.addView(view);
// set up the horizontal list view like before:
HorizontalListView hListView = (HorizontalListView) view.findViewById(R.id.hlistview1);
ListAdapter adapter = new SimpleAdapter(Su.this,eList,R.layout.view_m_ts, images, ins);
hListView.setAdapter(adapter);
}
If you have more HorizontalListViews than you can fit on screen then you might need to wrap your main LinearLayout in a ScrollView, however be warned that you might run into trouble with that, see this question.
I am currently developing a fragment which contains lists of albums.
The structure is pretty simple:
Horizontal slider contains LinearLayour (horizontal). In order to add an album with songs list I have created a separate view which consists of cover image and a listview. The listview is custom as well where items are linearlayout with 3 textviews. Then I inflate it, populate list, and add to the Horizontal slider.
The issue occurs if I have more than 2 album lists. It takes some time to open a fragment.
Another thing is when I try to scroll (horizontally), sometimes it stops for a short moment, which makes bad user experience.
What I am trying to say is that I have seen similar views and they work quickly and with no lags. Is it possible somehow to optimize it? Or is it possible so that the fragment opens straight away and then the lists load afterwards (kind of lazyload).
LISTVIEW ITEM:
<?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="#ccffffff"
android:padding="10dp" >
<TextView
android:id="#+id/album_list_item_number"
android:layout_width="30dp"
android:layout_height="wrap_content"
android:text=""
android:gravity="center|center_vertical"
android:layout_gravity="center|center_vertical"
android:textColor="#333333"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/album_list_item_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text=""
android:layout_weight="1"
android:gravity="left|center_vertical"
android:layout_gravity="left|center_vertical"
android:textColor="#333333"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/album_list_item_time"
android:layout_width="90dp"
android:layout_height="wrap_content"
android:text=""
android:gravity="center|center_vertical"
android:layout_gravity="center|center_vertical"
android:textColor="#333333"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
POPULATING THE LIST AND ADDING VIEW TO THE HORIZONTAL SLIDER:
View albumView = inflater.inflate(R.layout.artist_album_col, container, false);
//setting cover
ImageView albumCover = (ImageView) albumView.findViewById(R.id.artistAlbumCover);
albumCover.setImageDrawable(getResources().getDrawable(R.drawable.albumcover)); //cover
ListView albumList = (ListView) albumView.findViewById(R.id.artistSongList);
// create the grid item mapping
String[] from = new String[] {"num", "title", "time"};
int[] to = new int[] { R.id.album_list_item_number, R.id.album_list_item_title, R.id.album_list_item_time};
// prepare the list of all records
List<HashMap<String, String>> fillMaps = new ArrayList<HashMap<String, String>>();
for(int i = 0; i < 24; i++){
HashMap<String, String> map = new HashMap<String, String>();
map.put("num", "" + i);
map.put("title", "title title title title title title title title title " + i);
map.put("time", "time " + i);
fillMaps.add(map);
}
// fill in the grid_item layout
SimpleAdapter adapter = new SimpleAdapter(mContext, fillMaps, R.layout.album_list_item, from, to);
albumList.setAdapter(adapter);
albumContainer.addView(albumView);
You can use Async Task to perform the time-consuming tasks and take them off the UI thread. This will allow the fragment to load quickly and the list to populate "lazily".
Call with:
new LoadingTask().execute("");
And you can stick a class like this in your fragment class (warning! not tested):
private class LoadingTask extends AsyncTask<Void, Void, Void> {
SimpleAdapter adapter;
protected void doInBackground(Void... values) {
// do your work in background thread
// create the grid item mapping
String[] from = new String[] {"num", "title", "time"};
int[] to = new int[] { R.id.album_list_item_number, R.id.album_list_item_title, R.id.album_list_item_time};
// prepare the list of all records
List<HashMap<String, String>> fillMaps = new ArrayList<HashMap<String, String>>();
for(int i = 0; i < 24; i++){
HashMap<String, String> map = new HashMap<String, String>();
map.put("num", "" + i);
map.put("title", "title title title title title title title title title " + i);
map.put("time", "time " + i);
fillMaps.add(map);
}
// fill in the grid_item layout
adapter = new SimpleAdapter(mContext, fillMaps, R.layout.album_list_item, from, to);
return;
}
protected void onPostExecute(Void value) {
// back in UI thread after task is done
ListView albumList = (ListView) getActivity().findViewById(R.id.artistSongList);
albumList.setAdapter(adapter);
}
}
Another example here.
I have a file manager that uses a ListView (icon + text) .. and only for the photos(jpg) I want to show the preview instead of a default icon .. like es file explorer or similar...
and i would like to switch form single_selection listview.. to multiple_selection by long pressing a row on listview.. like happens on android messages system app... by highlightes on selected row... no checbox..
my actual scenario:
my ListView uses a RelativeLayout for each row
<?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="60dip"
android:padding="5dip">
<ImageView
android:id="#+id/fd_Icon"
android:layout_width="50dip"
android:layout_height="50dip"
>
</ImageView>
<TextView
android:text="Nome"
android:layout_marginLeft="5dip"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="#+id/fd_Text"
android:layout_toRightOf="#+id/fd_Icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"></TextView>
</RelativeLayout>
I have the class FileDirRow
public class FileDirRow {
private String file_dir_text;
private int file_dir_icon;
public FileDirRow( int file_dir_icon , String file_dir_text ) {
super();
this.file_dir_icon = file_dir_icon;
this.file_dir_text = file_dir_text;
}
public String getFileDirText() {
return file_dir_text;
}
public int getFileDirIcon() {
return file_dir_icon;
}
}
and I fill the listview like this
..........
//arrayItemT contains all files and directories of the current path
ArrayList<FileDirRow> lista_file_dir =new ArrayList<FileDirRow>();
for(int i=0;i<arrayItemT.size();i++){
if (arrayItemT.get(i).endsWith("/"))
lista_file_dir.add(new FileDirRow(R.drawable.folder, arrayItemT.get(i)));
else
-----------------------------------------------------------------------------
//if it's a photo add thumbnails or if it's a generic file...
lista_file_dir.add(new FileDirRow(R.drawable.file, arrayItemT.get(i)));
-----------------------------------------------------------------------------
}
//popolate list
ArrayList<HashMap<String, Object>> data=new ArrayList<HashMap<String,Object>>();
for(int i=0;i<arrayItemT.size();i++){
FileDirRow p= lista_file_dir.get(i);
HashMap<String,Object> rowMap=new HashMap<String, Object>();//create value map
rowMap.put("image", p.getFileDirIcon()); //for image key,image res
rowMap.put("name", p.getFileDirText()); //for name key,l'informazine sul nome
data.add(rowMap); //add value map to data source
}
String[] from={"image","name"}; //from value under this key
int[] to={R.id.fd_Icon,R.id.fd_Text};//to views id
//create adapter
SimpleAdapter adapter=new SimpleAdapter(
getApplicationContext(),
data,//sorgente dati
R.layout.icon_row, //layout
from,
to);
//use adapter
((ListView)findViewById(R.id.FileDirList)).setAdapter
I generated a ListView as seen below
I don't have enough rep to post images, you'll have to decipher my URL: image
The blue rows in the above image are populated using HashMap:
private void showListView(JSONArray rows, JSONArray totals){
final ListView list = (ListView) findViewById(R.id.historylist);
ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
HashMap<String, String> map;
String[] titles = new String[]{"recordID","date","description","num1","num2"};
SimpleAdapter mSchedule = null;
try{
for(int i=0;i<rows.length();i++){
map = new HashMap<String, String>();
for(int n=0;n<allRows.getJSONArray(i).length();n++){
map.put(titles[n], allRows.getJSONArray(i).getString(n));
}
mylist.add(map);
}
mSchedule = new SimpleAdapter(
History.this,
mylist,
R.layout.history_row,
titles,
new int[] {R.id.textView0, R.id.textView1, R.id.textView2, R.id.textView3, R.id.textView4}
);
list.setAdapter(mSchedule);
}catch(Exception e){
Log.e("Creating ListView", e.toString());
}
}
<LinearLayout >
<LinearLayout >
<LinearLayout >
<TextView (recordID) />
<TextView (date) />
<TextView (num1) />
<TextView (num2) />
</LinearLayout>
<TextView (description) />
</LinearLayout>
<LinearLayout (When this one is clicked) >
<ImageView />
</LinearLayout>
When the green button in the above image is clicked, Id like to get the blue row information.
(date, description, num1, num2)
Also, if you think there's a better way to populate the ListView, please let me know.
You will need to implement your own custom adapter by extending BaseAdapter. In the getView method you'll need to bind to that Button's click event. I suggest having one instance of OnClickListener and using AdapterView#getPositionForView. Once you have the position for the view holding the button that was clicked then you can get to your data. Either via Adapter#getItem or directly from your data source.