I've got a question.
I've made a database (Array) with different like, name, id, type.
Also I've made string that reads the name (name is a string:
public static String[] getAllPokemonsInStrings() {
ArrayList<String> items = new ArrayList<String>();
for(Pokemon p : Pokemon.values()){
if(p.getName() != null){
items.add(p.getName());
}
}
return items.toArray(new String[]{});
}
Here's the bit that creates it:
public class Test3 extends ListActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, R.id.label, Types.getAllPokemonsInStrings() ));
}
}
And the xml per row:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:id="#+id/LinearLayout">
<ImageView
android:id="#+id/sprite"
android:layout_width="96dp"
android:layout_height="96dp"
android:contentDescription="#string/sprite"
android:src="#drawable/p002" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/label"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dip"
android:textSize="16dip"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
Is there a way to change the imageresource (which is an int) doing that per row, loading it from the array?
Yes it is possible. You gonna need to create your own adapter class though and Override getView(). I would recommend you read this tutorial on how to create a custom adapter.
Related
I have a ArrayList<String> taskList; to which I add strings. Then I connect them to an ArrayAdapter with
if (mAdapter == null) {
mAdapter = new ArrayAdapter<>(this,
R.layout.item_todo,
R.id.task_title,
taskList);
mTaskListView.setAdapter(mAdapter);
} else {
mAdapter.clear();
mAdapter.addAll(taskList);
mAdapter.notifyDataSetChanged();
}
item_todo.xml looks like this
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/task_title"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:text="Text"
android:layout_weight=".3"
android:textSize="20sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight=".9"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
...
</LinearLayout>
<TextView
android:id="#+id/tvKategorie"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:gravity="center_horizontal"
android:text="Kategorie" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
Before, there was no
<TextView
android:id="#+id/tvKategorie"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:gravity="center_horizontal"
android:text="Kategorie" />
How do I fill not only task_title but also tvKategorie with content?
My ideas:
Create a new class EntryCategory to then create an ArrayList<EntryCategory> taskList; with fields task_title and tvKategorie.
Still the question remains how to assign task_title of taskList and tvKategorie of taskList to mAdapter so it shows in each item in my list?
Best way to achieve this is by using RecyclerView.
But if you still want to use ListView, I am providing one of the many solutions bellow:
mAdapter = new ArrayAdapter<EntryCategory>(this,
R.layout.item_todo, R.id.task_title,
taskList) {
#Override
public View getView (int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
TextView tvTaskTitle = (TextView) view.findViewById(R.id.task_title);
TextView tvKategorie = (TextView) view.findViewById(R.id.tvKategorie);
EntryCategory item = getItem(position);
tvTaskTitle.setText(item.getTaskTitle());
tvKategorie.setText(item.getKategorie());
return view;
}
};
Please excuse any syntax error as I am answering from my mobile.
Update:
Please pass R.id.task_title as the 3rd parameter in the ArrayAdapter's constructor. So, the new code will look like the following,
mAdapter = new ArrayAdapter<EntryCategory>(this,
R.layout.item_todo, R.id.task_title,
taskList) {
.....
}
I want to display a list of items containing 2 textview in one of my fragment. Something really simple since I'm learning how to use listviews.
Here is my code:
public class CommandeFragment extends Fragment{
private BarMenu myMenu;
View myView;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
myView = inflater.inflate(R.layout.commande_layout,container, false);
myMenu = (BarMenu) getArguments().getSerializable(MENU_KEY);
List<HashMap<String,String>> aList = new ArrayList<HashMap<String,String>>();
for(int i = 0; i < myMenu.drinks.size(); i++){
HashMap<String,String> hm = new HashMap<String, String>();
hm.put("Name",myMenu.drinks.get(i).drinkName);
hm.put("Price",myMenu.drinks.get(i).drinkPrice.toString());
aList.add(hm);
}
String[] from = {"drinkName","drinkPrice"};
int[] to = {R.id.textView3,R.id.textView4};
SimpleAdapter adapter = new SimpleAdapter(myView.getContext(), aList, R.layout.listview_commande_layout, from, to);
ListView listView = (ListView) myView.findViewById(R.id.listView);
listView.setAdapter(adapter);
return myView;
}
}
When I run this, I got a list of textviews placed correctly but the problem is that the text inside is empty. I've try multiple advice about the xml files online but I'm pretty sure it's fine.
Here it is in case:
listview_commande_layout.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">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/textView3"
android:layout_weight="1" />
<TextView
android:text="TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/textView4"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout>
commande_layout.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">
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:text="Bar Menu Layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="102dp"
android:id="#+id/textView2" />
</RelativeLayout>
The column names you pass to your adapter don't match the column names in your HashMap ("Name" vs. "drinkName"). If you update these to match, it should work.
for(int i = 0; i < myMenu.drinks.size(); i++){
HashMap<String,String> hm = new HashMap<String, String>();
hm.put("Name",myMenu.drinks.get(i).drinkName);
hm.put("Price",myMenu.drinks.get(i).drinkPrice.toString());
aList.add(hm);
}
String[] from = {"Name","Price"}; //changed from {"drinkName","drinkPrice"}
I want to display all items of an ArrayList<String> on a ListView. I use an ArrayAdapter<String> for this. The problem is that only the first item ('foo' in my example) of the ArrayList is shown. Can someone tell me why? Am I missing something?
I've made an minimal example using the generated code (Tabbed Action Bar Spinner Activity) from Android Studio 2.
My FooActivity:
public class FooActivity extends AppCompatActivity {
...
public static class PlaceholderFragment extends Fragment {
private ListView fooListView;
private ArrayAdapter<String> mAdapter;
...
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_foo, container, false);
fooListView = (ListView) rootView.findViewById(R.id.foo_list);
updateList();
return rootView;
}
private void updateList() {
ArrayList<String> strings = new ArrayList<>();
strings.add("foo");
strings.add("bar");
if (mAdapter == null) {
mAdapter = new ArrayAdapter<>(getContext(),
R.layout.item_foo,
R.id.foo_string,
strings);
fooListView.setAdapter(mAdapter);
} else {
mAdapter.clear();
mAdapter.addAll(strings);
mAdapter.notifyDataSetChanged();
}
}
}
My fragment_foo.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="com.foo.activities.FooActivity$PlaceholderFragment">
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/foo_list"
android:layout_below="#+id/total_activities"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="10dp"
android:layout_alignParentBottom="true" />
</RelativeLayout>
And the item_foo.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">
<TextView
android:id="#+id/foo_string"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="some_string"
android:textSize="20sp"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</LinearLayout>
If it helps I can post the generated activity_foo.xml (I didn't made any changes there) and the complete FooActivity class too.
The Problem actually was my activity_foo.xml which had a NestedScrollView. I've added android:fillViewport="true" and now it shows every item.
My NestedScrollView now looks like this:
<android.support.v4.widget.NestedScrollView
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:fillViewport="true"/>
On any ListView, if you use android:layout_height="wrap_content", you're only going to see one item. Try android:layout_height="match_parent". If the ListView only takes up part of the layout, you'll need a LinearLayout with weights or a RelativeLayout with constraints. But wrap_content won't work for a height on a ListView, ever.
Your Listview look something like this
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/foo_list"
android:layout_marginTop="10dp"/>
I have removed from your list view android:layout_below="#+id/total_activities"
and
android:layout_alignParentBottom="true"
For others: It's okay to nest a ListView inside another layout, and it's also fine to use android:layout_height="wrap_content" on Layouts surrounding the ListView. (So long as the outer-most Layout allows for match_parent)
What is not fine, however, is when the TextView being used to populate the ListView is defined with layout_height="match_parent". It will cover up all of the subsequent rows after the first.
Bad:
<TextView
android:id="#+id/infoRow_textView"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
Good:
<TextView
android:id="#+id/infoRow_textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
I am using two list adapter as shown on code below. resultList and resultList2 are initialized with new ArrayList <HashMap<String,String>>();
ListAdapter adapter, adapter2;
adapter =new SimpleAdapter(
getActivity(), resultList,
R.layout.list_item1, new String[]{TAG_ID, TAG_FRUIT, TAG_SPECIES},
new int[]{R.id.Id,R.id.fruit,R.id.species});
adapter2=new SimpleAdapter(
getActivity(), resultList2,
R.layout.list_item_append, new String[]{ TAG_NAME, TAG_ADDRESS, TAG_EMAIL},
new int[]{ R.id.name, R.id.address, R.id.email});
setListAdapter(adapter);
setListAdapter(adapter2); //this line has overriden setListAdapter(adapter)
I have two layouts named list_item1.xml and list_item2.xml.
//list_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/Id"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="6dip"
android:paddingLeft="6dip"
android:textSize="17sp"
android:textStyle="bold"
android:descendantFocusability="blocksDescendants"
android:visibility="gone"/><!--android:visibility="gone" -->
<TextView
android:id="#+id/fruit"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="6dip"
android:paddingLeft="6dip"
android:textSize="17sp"
android:textStyle="bold" />
<TextView
android:id="#+id/species"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="6dip"
android:paddingLeft="6dip"
android:textSize="17sp"
android:textStyle="bold" />
</LinearLayout>
second layout: list_item2.xml
list_item.xml
<TextView
android:id="#+id/name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="6dip"
android:paddingLeft="6dip"
android:textSize="17sp"
android:textStyle="bold" />
<TextView
android:id="#+id/address"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="6dip"
android:paddingLeft="6dip"
android:textSize="17sp"
android:textStyle="bold" />
<TextView
android:id="#+id/email"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="6dip"
android:paddingLeft="6dip"
android:textSize="17sp"
android:textStyle="bold" />
I have tried to use <include> and <merge> in my new layout but it is not the result I wanted. The result shows all the elements in adapter2. But there are empty list element before each of the adapter2 elements.
My expected result are:
adapter....
adapter....
adapter...
adapter2...
adapter2...
adapter2...
How can I achieve this? I think that setListAdapter is the cause of the problem.
The reason i used two listadapter is because i am trying two fetch two set of data from my database. The data is fetch from the table named tblfruit and tblperson.
$response["results"] = array();
$response["results2"] = array();
// temp user array
$results = array();
$results2=array();
while ($row = mysql_fetch_array($result)){
$results["id"] = $row["id"];
$results["fruit"] = $row["fruit"];
$results["species"] = $row["species"];
array_push($response["results"], $results);
}
while ($row = mysql_fetch_array($result2)){
$results2["name"] = $row["name"];
$results2["address"] = $row["address"];
$results2["email"] = $row["email"];
array_push($response["results2"], $results2);
}
Extend ListAdapter and inflate each row with your desired layout within the Adapter's View.getView() method. This method is called once for each row in the ListView (or record inside the adapter, if you want to be specific). It is used to set up (or, well, inflate) the view for each record, and doing things such as setting the value of TextView's, ImageView's, hiding unnecessary components for each row, etc. I haven't tried this with two differente layout resources myself, but I suppose it can be done with this approach.
public class CustomListAdapter extends ArrayAdapter<CustomObject> {
private Context context;
private int layoutResourceId_1;
private int layoutResourceId_2
private List<CustomObject> list;
public CustomListAdapter(Context context, int layoutResourceId_1, int layoutResourceId_2, List<CustomObject> list) {
super(context, layoutResourceId_1, list);
this.context = context;
this.layoutResourceId_1 = layoutResourceId_1;
this.layoutResourceId_2 = layoutResourceId_2;
this.list = list;
}
...
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
LayoutInflater layoutInflater = ((Activity) context).getLayoutInflater();
if(condition_layout_1()) {
row = layoutInflater.inflate(layoutResourceId_1, parent, false);
// Use a holder to prepare item
...
} else {
row = layoutInflater.inflate(layoutResourceId_2, parent, false);
// Use a holder to prepare item
...
}
return row;
}
...
}
You don't need to merge list_item1 and resultList2 layouts for whatever you are trying to achieve.Instead of extending ListActivity or ListFragment, use ordinary activity and setContentView with a layout that has two listviews in its xml like below
<?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:gravity="center"
android:orientation="vertical" >
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</ListView>
<ListView
android:id="#+id/listView2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</ListView>
and then in your java file
ListView listview1 = (ListView) findViewById(R.id.listView1);
ListView listview2 = (ListView) findViewById(R.id.listView2);
listview1.setAdapter(adapter);
listview2.setAdapter(adapter2);
I am not sure if this meets your requirement.Sorry if it doesn't.I hope it helps.
I'm trying to get my ArrayList of HashMaps to try to get a working ListAdapter. When I run this, I'm getting a
java.lang.RuntimeException: Your content must have a ListView whose id attribute is android.R.id.list
error. Here's what I have:
gameList is where I'm getting my data from:
gameList.toString() returns: [{turn=1, opponent=UserTwo, streak=4, hintX=1234, player=UserOne, solution=MySolution, hintY=5678}, {turn=0, opponent=UserThree, streak=12, hintX=1344, player=UserOne, solution=SolutionTwo, hintY=5428}]
My ListActivity class:
public class GameListActivity extends ListActivity{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.game_list);
String GAME_ITEM = "game";
String PLAYER_ITEM = "player";
String OPPONENT_ITEM = "opponent";
String SOLUTION_ITEM = "solution";
String HINTX_ITEM = "hintX";
String HINTY_ITEM = "hintY";
String STREAK_ITEM = "streak";
String TURN_ITEM = "turn";
ArrayList<HashMap<String, String>> gameList = new ArrayList<HashMap<String, String>>();
AppVars gameVars = ((AppVars) getApplicationContext());
gameList = gameVars.getState();
String[] keyList = new String[] { OPPONENT_ITEM, STREAK_ITEM, TURN_ITEM };
ListAdapter adapter = new SimpleAdapter(this, gameList, R.layout.game_list_item,
keyList,
new int[] {R.id.opponent, R.id.streak, R.id.turn});
setListAdapter(adapter);
}
XML:
game_list_item.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="wrap_content"
android:padding="5dp" >
<ImageView
android:id="#+id/thumbnail"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentTop="true"
android:src="#android:drawable/alert_dark_frame" />
<TextView
android:id="#+id/opponent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/thumbnail"
android:layout_centerHorizontal="true"
android:text="Entry"
android:textSize="30sp" />
<TextView
android:id="#+id/streak"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/thumbnail"
android:layout_centerHorizontal="true"
android:text="Streak"
android:textSize="20sp" />
<TextView
android:id="#+id/turn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/streak"
android:layout_centerHorizontal="true"
android:text="Your turn!"
android:textSize="20sp" />
</RelativeLayout>
game_list.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:background="#drawable/blackboard" >
<ListView
android:id="#+id/gameList"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
</ListView>
</RelativeLayout>
java.lang.RuntimeException: Your content must have a ListView whose id
attribute is android.R.id.list
So error log tells you everything
You need to add to your XML file of ListView android.R.id.list
<ListView
android:id="#android:id/list"
// next attributes
/>
Exactly when your Activity extends from ListActivity, you should to use this.
Here is info from docs
ListActivity has a default layout that consists of a single,
full-screen list in the center of the screen. However, if you desire,
you can customize the screen layout by setting your own view layout
with setContentView() in onCreate(). To do this, your own view MUST
contain a ListView object with the id "#android:id/list" (or list if
it's in code)
So for more information have look at ListActivity.
Mind that When you extends ListActivity Then your xml file must have listview which id is
#android:id/list.
USe #android:id/list
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
</ListView>
You are extending ListActivity, so your view should have list defined with id "list"
See this link for working example.
id of list is "#+id/gameList" should be "#android:id/list" as you are using ListActivity...
Remove the following line from your code:
setContentView(...)
ListActivity handles the ListView for you so you access the ListView using this.
If you need a more complex layout subclass Activity instead.