I KNOW this is a repost, but I've been trying to get this to work for ages (hours) now and I really can't understand the existing answers.
All i want to know is: How can I edit this code so it works? I'm trying to populate both textviews from two different arrays.
Only the second adapter gets read and the first one's textview stays blank.
Any help at all would be appreciated.
public void run () {
if (t.getState() == Thread.State.TERMINATED) {
adapter2 = new ArrayAdapter<String>(getApplicationContext(), R.layout.listlook, R.id.txtl2, names);
setListAdapter(adapter2);
adapter = new ArrayAdapter<String>(getApplicationContext(), R.layout.listlook, R.id.txtl1, comments);
setListAdapter(adapter);
return;
} else {
h.postDelayed(this, 1000);
}
}}
, 1000);
}
Thanks in advance.
Listview within Usercomments.xml
<ListView
android:id="#+android:id/list"
android:layout_width="match_parent"
android:layout_height="150dp" >
</ListView>
listlook.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/txtl1"
android:paddingLeft="2dp"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="#0000FF"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="TextView" />
<TextView
android:id="#+id/txtl2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/txtl1"
android:gravity="bottom|right"
android:paddingLeft="5dp"
android:text="TextView"
android:textColor="#5C002E"
android:textSize="15sp" />
</RelativeLayout>
listlook is just the layout i use in the listview? Don't really know what I'm doing.
You're telling your list view that you want to use adapter2, and then telling it you want to use adapter - it can only read data from one adapter at a time.
If you want to display data from two lists, you could do something like this.
First, combine your two lists into a class, and build a List<Post> of these, instead of having two arrays:
public class Post {
String mName, mComment;
public Post(String name, String comment) {
mName = name;
mComment = comment;
}
public String getName() {
return mName;
}
public String getComment() {
return mComment;
}
}
Then, write an adapter that knows how to display Post items:
public class PostAdapter extends BaseAdapter {
private Activity mActivity;
private List<Post> mPosts;
public TweetstreamAdapter(Activity activity, List<Post> posts) {
mActivity = activity;
mPosts = posts;
}
#Override
public int getCount() {
return mPosts.size();
}
#Override
public Post getItem(int position) {
return mPosts.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Post post = getItem(position);
if (convertView == null) {
convertView = mActivity.getLayoutInflater().inflate(R.layout.listlook, parent, false);
}
((TextView)convertView.findViewById(R.id.txtl1)).setText(post.getName());
((TextView)convertView.findViewById(R.id.txtl2)).setText(post.getComment());
return convertView;
}
}
Then in your activity, you set the adapter like this:
setListAdapter(new PostAdapter(this, posts));
where posts is a List<Post> of posts.
Note: You'll need to ensure you have TextView entries in your listlook layout that have IDs that match those that the adapter is searching for. Update the code to match your IDs accordingly. Updated to match your id's. This should just drop in, provided you construct a list of Post objects correctly.
Update 2: You could build a list like this, assuming the two arrays (names/comments) are the same length:
List<Post> posts = new ArrayList<Post>();
for(int i = 0; i < names.length; i++) {
posts.add(new Post(names[i], comments[i]);
}
You have two lines with setListAdapter(). The second overwrite the first. If you have two ListViews then do this:
listView1.setListAdapter(adapter2);
listView2.setListAdapter(adapter);
Related
This is an advanced data manipulation of sorting and showing the data. I have an array list of objects let's say
ArrayList<PersonDetails> personList= new ArrayList<>();
personList.add(name:"George",date:"25-DEC-2019",duration:"30mins",time:"9:45",slot:"Morning",exercise-type:"Leg-Exercise");
personList.add(name:"Ramesh",date:"25-DEC-2019",duration:"30mins",slot:"9:45","Morning",exercise-type:"Leg-Exercise");
personList.add(name:"Joslin",date:"25-DEC-2019",duration:"30mins",slot:"9:45","Morning",exercise-type:"Arms-Exercise");
personList.add(name:"Hrithik",date:"25-DEC-2019",duration:"30mins",slot:"9:45","Morning",exercise-type:"Arms-Exercise");
all data type are string.so, I have to operate on this list and show the final result something like this on a recyclerview. I want to group persons which have the same exercise type and there individual in one object. also I want to count the person who has the same exercise type.
Details
-----------------------------------------------------
Exercise-type Leg-exercise
Person 2
-----------------------------------------------------
George
Date 25-Dec-2019
Duration 30mins
Time 9:45
Slot Morning
Ramesh
Date 25-Dec-2019
Duration 30mins
Time 9:45
Slot Morning
Details
-----------------------------------------------------
Exercise-type Arms-exercise
Person 2
-----------------------------------------------------
Joslin
Date 25-Dec-2019
Duration 30mins
Time 9:45
Slot Morning
Hrithik
Date 25-Dec-2019
Duration 30mins
Time 9:45
Slot Morning
This is my item_detail_order.xml file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/fieldItems"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:layout_marginBottom="16dp"
>
<TextView
android:id="#+id/detail_item_key"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:fontFamily="#font/montserrat_medium_0"
android:text="detail_items"
android:textColor="#color/colorBody">
</TextView>
<TextView
android:id="#+id/detail_item_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_marginEnd="8dp"
android:fontFamily="#font/montserrat_semibold_0"
android:text="detail_values">
</TextView>
</RelativeLayout>
here the id - detail_item_key is for example the name or duration, or slot,etc.
and the id - detail_item_valueis for example the corresponding value from the name,duration and slot.
DetailObjectAdapter.java
public class DetailsObjectAdapter extends RecyclerView.Adapter<DetailsObjectAdapter.DetailsObjectViewHolder> {
ArrayList<DetailsObject> detailsObjectList = new ArrayList<>();
public DetailsObjectAdapter(ArrayList<DetailsObject> detailsList) {
detailsObjectList = detailsList;
}
#NonNull
#Override
public DetailsObjectViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.item_details_summary, parent, false);
return new DetailsObjectViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull DetailsObjectViewHolder holder, int position) {
DetailsObject detailsObject = detailsObjectList.get(position);
holder.detailsItemKey.setText(detailsObject.getNamekey());
holder.detailsItemValue.setText(detailsObject.getNameValue());
}
#Override
public int getItemCount() {
return detailsObjectList.size();
}
public class DetailsObjectViewHolder extends RecyclerView.ViewHolder {
#BindView(R.id.detail_item_key)
TextView detailsItemKey;
#BindView(R.id.detail_item_value)
TextView detailsItemValue;
public DetailsObjectViewHolder(#NonNull View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
}
I tried grouping the exercise-type with hashmap but it will result in a whole new string. which then I have to manipulate it line by line. Which I don't generally prefer.
I really don't want you all to write the whole code for me. Just a way to tell me exactly how to approach this? like a pseudo code.or something?
DetailsObject.java
public class DetailsObject {
String namekey;
public DetailsObject(String namekey, String nameValue) {
this.namekey = namekey;
this.nameValue = nameValue;
}
public String getNameValue() {
return nameValue;
}
public String getNamekey() {
return namekey;
}
String nameValue;
}
Make a new HashMap < String, ArrayList < Details Object > >. Segregate the list of object of a type into a List and add to this HashMap using the key Exercise type.
When you have to show this data in a recyclerview you can make two viewholders one will show the Exercise header and count of the people and other will show details of the people.
Follow examples like these to generate a single list that will be passed to your recycler view Adapter.
you have to add two checks first for exercise and second for date.
Create two separate list one for exercise and second for data.
ArrayList<String> exerciseType=new ArrayList()
ArrayList<String> dateList=new ArrayList()
now add all exercises in arrrayList but do add contains check to avoid duplicate entries same for date.
now use loop and create a separate array for each exercise and save them to HashMap<String,ArrayList<DetailModel>> exerciseArrays=new HashMap()
I am trying to create ListView with custom data set as follows:
String superType = "random1";
String superTypea = "random12";
String superType12 = "random2";
String superType_amount = "child1";
String childtype_calulated = "2323";
String superType_amount = "child2";
String childtype_calulated = "23223";
String superType_amount = "child2";
String childtype_calulated = "amount3";
Now I want to create ListView with this set of data how to do that?
Here is the list structure...
row1=superType |superType_amount |childtype_calulated
row2=superTypea |superType_amount |childtype_calulated
row3=superType12|superType_amount |childtype_calulated
Is there any solution of this?
It is absolutely possible to do this. First, I would recommend putting your data into a collection. It would be preferable to put them into an object and then a collection of those objects. From there you can add a ListView to your main layout, define a custom layout for your list items, and populate your ListView using an ArrayAdapter.
Here is a really good example of how you can do this well. It includes examples of loading data from an external source, which you don't need.
However, if you're getting into development now I would suggest you look into RecyclerView as well. RecyclerView is new and included in the AppCompat v7 library for use on pre-Lollipop Android. A RecyclerView will be a little more complicated to implement for a simple list but is significantly more scalable and efficient. I believe it is Google's intention to replace ListView with RecyclerView entirely in the future.
Here is a pretty simple introduction to making a list with RecyclerView.
EDIT
Using an ArrayAdapter with a ListView. First you need to create a model to store your data, some kind of class that you can put into a collection, for example:
public class Item {
public String title;
public String sub1;
public String sub2;
public void Item(String t, String s1, String s2) {
title = t;
sub1 = s1;
sub2 = s2;
}
}
Then you need to define the layout for the item in your list:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/sub1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/sub2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Then in you need to make your custom ArrayAdapter by extending the ArrayAdapter class:
public class ItemAdapter extends ArrayAdapter<Item> {
public ItemAdapter(Context context, ArrayList<Item> items) {
super(context, 0, items);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Item item = getItem(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_layout, parent, false);
}
TextView title = (TextView) convertView.findViewById(R.id.title);
TextView sub1 = (TextView) convertView.findViewById(R.id.sub1);
TextView sub2 = (TextView) convertView.findViewById(R.id.sub2);
title.setText(item.title);
sub1.setText(item.sub1);
sub2.setText(item.sub2);
return convertView;
}
}
Then all you need to do is create an instance of the adapter in your main class and attach your collection to it:
ArrayList<Item> data = new ArrayList<Item>();
ItemAdapter adapter = new ItemAdapter(this, data);
ListView listView = (ListView) findViewById(R.id.list_view);
listView.setAdapter(adapter);
This should populate your ListView with all the items that you need in your list. I haven't run any of this code so there might be one or two small bugs for you to fix.
I am new in android and i am using list view that is coming from the database . Now , I want to add two icons in it , one for edit and one for delete. Here is my java code that is currently working
public void ListDrwaer() {
List<Map<String, String>> employeeList = new ArrayList<Map<String, String>>();
try {
JSONObject jsonResponse = new JSONObject(jsonResult);
JSONArray jsonMainNode = jsonResponse.optJSONArray("emp_info");
for (int i = 0; i < jsonMainNode.length(); i++) {
JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
String name = jsonChildNode.optString("cat_name");
number = jsonChildNode.optString("cat_id");
String outPut = name /*+ "-" + number*/;
employeeList.add(createEmployee("employees", outPut));
}
} catch (JSONException e) {
Toast.makeText(getApplicationContext(), "Error" + e.toString(),
Toast.LENGTH_SHORT).show();
}
SimpleAdapter simpleAdapter = new SimpleAdapter(this, employeeList,
android.R.layout.simple_list_item_1,
new String[] { "employees" }, new int[] { android.R.id.text1 });
listView.setAdapter(simpleAdapter);
}
private HashMap<String, String> createEmployee(String name, String number) {
HashMap<String, String> employeeNameNo = new HashMap<String, String>();
employeeNameNo.put(name, number);
return employeeNameNo;
}
can anyone tell me how to edit it to add the icons ?
As you told you are new so I am creating a listview similar to your needs. If you are still facing any problem then you can ask. There can be other methods also but I have followed below one.
I have created it in three steps:
1. Create a listview layout in XML.
2. Create a layout for your row which you will inflate and set on listview row.
3. Create a custom adapter by extending arrayadapter.
4. Setting custom adapter.
Step 1: Create a listview layout in XML.
Below given XML code will create a listview for you.
<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" >
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
</ListView>
</RelativeLayout>
Step 2: Create a layout for your row which you will inflate and set on listview row.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/RelativeLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="false"
android:layout_alignParentTop="false"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:text="TextView" />
<ImageButton
android:id="#+id/imageButton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginLeft="34dp"
android:layout_toRightOf="#+id/textView1"
android:src="#drawable/ic_launcher" />
<ImageButton
android:id="#+id/imageButton2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginLeft="16dp"
android:layout_toRightOf="#+id/imageButton1"
android:src="#drawable/ic_launcher" />
</RelativeLayout>
Step 3:Create a custom adapter by extending arrayadapter.
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
public class my_list_adapter extends ArrayAdapter<String> {
private Context context;
private ArrayList<String> labels;
public my_list_adapter(Context context, ArrayList<String> labels) {
super(context, R.layout.list_layout, labels);
this.context = context;
this.labels = labels;
}
static class ViewHolder {
public TextView textView1;
public ImageButton icon_1;
public ImageButton icon_2;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
View rowView = convertView;
if (rowView == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
rowView = inflater.inflate(R.layout.list_layout, null, true);
holder = new ViewHolder();
holder.textView1 = (TextView) rowView.findViewById(R.id.textView1);
holder.icon_1 = (ImageButton) rowView.findViewById(R.id.imageButton1);
holder.icon_2 = (ImageButton) rowView.findViewById(R.id.imageButton2);
rowView.setTag(holder);
} else {
holder = (ViewHolder) rowView.getTag();
}
holder.textView1.setText(labels.get(position));
holder.icon_1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context.getApplicationContext(), "bb icon 1 item clicked position = " + position, Toast.LENGTH_LONG).show();;
}
});
holder.icon_2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context.getApplicationContext(), "bb icon 2 item clicked position = " + position, Toast.LENGTH_LONG).show();;
}
});
return rowView;
}
}
Step 4: Setting custom adapter.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView list_view = (ListView) findViewById(R.id.listView1);
ArrayList<String> labels = new ArrayList<String>();
for (int i = 0; i < 10; i++) {
labels.add ("item " + i);
}
my_list_adapter adapter = new my_list_adapter(this, labels);
list_view.setAdapter(adapter);
}
I think above example can help you. Try to get the concept. If you are facing any problem then you can ask. I will try to help you.
Use CustomArray adapter to add edit/delete button. This tutorial will help you. please check it.
For this scenario you have to use ur custom adapter
means extends BaseAdapter
and try to implement all methods in that adapter.
It is confusing if you're new to Android, but there's no shortcut in learning how to do it. Try this tutorial as well, I found it pretty helpful:
http://theopentutorials.com/tutorials/android/listview/android-custom-listview-with-image-and-text-using-baseadapter
None of the tutorials are going to help you, because none show how to put a listener on a button in a listview in the getView() method of a custom ArrayAdapter and show you how to figure out what item in the listviev owns that button. Even if there is a way to do this, you then have to figure out how (from the ArrayAdapter class) to call a method back in your Activity or Fragment, where you can then act on that item.
So, this leaves you with several options. Instead of buttons, you need to respond to clicks/presses on the list item itself. This is done by adding an OnItemClickListener or OnItemLongClickListener to the listview. You can then respond to these actions in several ways:
A context menu, where the user can select the option to delete or
edit the item (using a listview of menu options).
A pop-up Dialog that does the same thing with buttons. Ot it could put them in edit mode and have a delete button too.
Since you are going to need to write a Dialog for the editing of the item, I would go with the Dialog option.
I have a ListView that gets TutorialTitels from the string file like so
public class tutorialActivity extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tutorial);
registerClickCallBack();
ListView listView = (ListView) findViewById(R.id.tutorialList);
String tutorialTitle1 = getResources().getString(R.string.tutorial1_title);
String tutorialTitle2 = getResources().getString(R.string.tutorial2_title);
String tutorialTitle3 = getResources().getString(R.string.tutorial3_title);
String tutorialTitle4 = getResources().getString(R.string.tutorial4_title);
String tutorialTitle5 = getResources().getString(R.string.tutorial5_title);
String tutorialTitle6 = getResources().getString(R.string.tutorial6_title);
String tutorialTitle7 = getResources().getString(R.string.tutorial7_title);
String tutorialTitle8 = getResources().getString(R.string.tutorial8_title);
String tutorialTitle9 = getResources().getString(R.string.tutorial9_title);
String tutorialTitle10 = getResources().getString(R.string.tutorial10_title);
String tutorialTitle11 = getResources().getString(R.string.tutorial11_title);
String tutorialTitle12 = getResources().getString(R.string.tutorial12_title);
String tutorialTitle13 = getResources().getString(R.string.tutorial13_title);
String tutorialTitle14 = getResources().getString(R.string.tutorial14_title);
String[] values = new String[] { tutorialTitle1, tutorialTitle2, tutorialTitle3, tutorialTitle4, tutorialTitle5, tutorialTitle6, tutorialTitle7, tutorialTitle8, tutorialTitle9, tutorialTitle10, tutorialTitle11, tutorialTitle12, tutorialTitle13, tutorialTitle14};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1, values);
listView.setAdapter(adapter);
}
private void registerClickCallBack() {
ListView list = (ListView) findViewById(R.id.tutorialList);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View viewClicked,int position, long id) {
}
});
}
}
When I click on a listViewItem then I'd like to open up an Activity that'll show the following things:
The clicked TutorialTitel
Tutorial content (This will also come from a string file, like so
String tutorialContent1 = getResources().getString(R.string.tutorial1_content);)
Tutorial example ((This will also come from a string file, like so
String tutorialExample1 = getResources().getString(R.string.tutorial1_example);))
I already have an XML file like so
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:background="#FFFFFF"
android:orientation="vertical"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp" >
<TextView
android:id="#+id/tutorialTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Title"
android:textSize="25sp" />
<LinearLayout
android:id="#+id/split"
android:layout_width="fill_parent"
android:layout_height="2dip"
android:layout_marginBottom="15dp"
android:layout_marginLeft="25dp"
android:layout_marginRight="25dp"
android:layout_marginTop="5dp"
android:background="#38b34a"
android:orientation="horizontal" />
<TextView
android:id="#+id/tutorialContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:text=""/>
<TextView
android:id="#+id/tutorialExample"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:text=""/>
</LinearLayout>
</RelativeLayout>
</ScrollView>
The question: How do I pass the data to my activity corresponding to my clicked ListviewItem? should I do something like
if(position == 0){
//Send data through extra bundle
}
else if(position == 1){
//send data through extra bundle
}
But there should be a better way I think, but I don't know how exactly, because what if I'll getting 100 tutorials how should I manage a list long like that?
Can someone point me in the correct direction and what is the best approach to do this?
You can add a listener to ListView using setOnItemClickListener(); this listener callback will give three parameter as onItemClick (AdapterView<?> parent, View view, int position, long id) in which position will give the position of the list item clicked.
so using this position you can use as values[position] and same for tutorialContent and tutorialExample and pass it in intent and start Activity with this intent having the selected item data
This is a Quick solution for your problem. But i will not recommend because the way you have implemented is not in the object oriented standard.
I recommend you to create a model class for Tutorial with having member variable title, content, and example.
Class Tutorial{
private String title;
private String content;
private string example;
}
and pass this object in the intent.
First keep your strings in an array file (array.xml). Then read them to an String array;
String [] myresources=resources.obtainTypedArray(R.array.somelist);
for(int i=0;i<NumberOfTutorials;i++){
if(position==i){
//send myresources[i];
}
}
You can use enum. For example you can define Tutorials enum like this:
public enum Tutorials
{
TUTORIAL_1(R.string.tutorial1_title, R.string.tutorial1_content, R.string.tutorial1_example),
TUTORIAL_2(R.string.tutorial2_title, R.string.tutorial2_content, R.string.tutorial2_example),
TUTORIAL_3(R.string.tutorial3_title, R.string.tutorial3_content, R.string.tutorial3_example);
private int mTitleResourceId;
private int mContentResourceId;
private int mExampleResourceId;
private Tutorials(int titleResourceId, int contentResourceId, int exampleResourceId)
{
mTitleResourceId = titleResourceId;
mContentResourceId = contentResourceId;
mExampleResourceId = exampleResourceId;
}
public int getTitleResourceId()
{
return mTitleResourceId;
}
public int getContentResourceId()
{
return mContentResourceId;
}
public int getExampleResourceId()
{
return mExampleResourceId;
}
}
In this enum you can define 100 tutorials if you wish.
And then in your activity you can use it like this in generic way:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.tutorial);
ListView listView = (ListView) findViewById(R.id.tutorialList);
List<String> titlesList = new ArrayList<String>();
for (Tutorials tutorial: Tutorials.values())
{
titlesList.add(getResources().getString(tutorial.getTitleResourceId()));
}
String[] values = titlesList.toArray(new String[titlesList.size()]);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1, values);
listView.setAdapter(adapter);
}
And finally on click item on the list you can easily retrieve the Tutorial enum by its string title and then you will have the tutorial content and and tutorial example for free.
Once you set this code, you will add tutorials only to Tutorials enum and that's it.
Hope it helps. Of course, using sqlite is also an option.
This is a post to an answer that I could not really find a good solution to. I searched quite a bit and I couldn't find anything decent. I don't know if the method I'm using is the best way, but it works and i feel that it is a fairly clean solution.
Were going to make a few assumptions here.
that you know what a JSONArray is and have already somehow populated the JSONArray with some data.
{"result":
[
{"ACTIVE":"1","ID":"1","MAX_POPULATION":"1000","NAME":"Server 1","URL":"http://local.orbitaldomination.com/"},
{"ACTIVE":"1","ID":"2","MAX_POPULATION":"1000","NAME":"Server 2","URL":"http://server2.orbitaldomination.com/"}
]
}
This is my JSON code that is populated into my JSONArray.
You have already created a ListActivity with a ListView element inside it, and that you have created a layout. If you need more information on how to do that you can reference to Creating Lists Using the ListActivity
Okay, so here is where the real magic is..
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Pretty much ignore this .. it won't have anything to do with the example.
// Your setContentView should be your layout with your list element.
setContentView(R.layout.server_selection);
//psuedo code
//JArrayServers = JSONArray that has my data in it.
//Create a blank ( for lack of better term ) ArrayAdapter
ArrayAdapter<String> servers = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1);
//Loop though my JSONArray
for(Integer i=0; i< jArrayServers.length(); i++){
try{
//Get My JSONObject and grab the String Value that I want.
String obj = jArrayServers.getJSONObject(i).getString("NAME");
//Add the string to the list
servers.add(obj);
}catch(JSONException e){
}
}
//Add my Adapter via the setListAdapter function.
setListAdapter(servers);
//Display the listView
ListView lv = getListView();
lv.setTextFilterEnabled(true);
}
I am creating a blank ArrayAdapter from what I can tell. I then loop though the array getting my string and inserting it into the adapter as I move along. Finally, at the end of the loop, I am inserting the adapter via the setListAdapter() function.
Pretty simple I think, but took a lot of research to come up with this, from a rookie. I'm sure all you experts out there will have a better way. If you do, post it somewhere easy to find please!
The best way to achieve this is in fact to roll your own custom adapter that extends BaseAdapter. I struggled with this issue for a day trying to avoid doing a pointless iteration of a JSONArray just to fill an array and use it in a "normal" ArrayAdapter. My situation was very similar to yours, with the small diference that i wanted to populate a spinner and not a ListView. Despite that, i will post the solution i found, because it may be helpful to you or someone else.
In your activity class:
public void initSpinner(JSONArray jsonArray)
{
Spinner spinner = new Spinner(this);
JSONArrayAdapter jsonArrayAdapter = new JSONArrayAdapter(this, countries, "Name");
spinner.setAdapter(jsonArrayAdapter);
}
NOTE: the string "name" i pass has a parameter to my adapter is simply the key i wish to look for in my json data, in your case, it might be whatever key you are looking for.
Next, you need to roll your own spinner list item, wrapped in a RelativeLayout. I did this in a file called spinner_item.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="5dip" >
<TextView
android:id="#+id/spinnerListItemName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:textColor="#000000"
android:textSize="16dip" />
<RadioButton
android:id="#+id/spinnerRadioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:paddingRight="6dip"
android:focusable="false"
android:clickable="false" />
<TextView
android:id="#+id/spinnerListItemID"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible" />
</RelativeLayout>
NOTE: the text view with id spinnerListItemID i just use because i want to store the id of the last button that i chose to simulate the behavior of a RadioButtonGroup, its very likely that there is a better way to acomplish this task, this is just the way that i found suited better at the time.
Finally, and most importantly, you need to create your JsonArrayAdapter class:
public class JSONArrayAdapter extends BaseAdapter implements OnTouchListener
{
private ViewGroup group;
private JSONArray items;
private String key;
private Context context;
private String selectedItemID;
private int selectedItemPosition;
public JSONArrayAdapter(Context ctx, JSONArray array, String k)
{
super();
this.items = array;
this.context = ctx;
this.key = k;
this.selectedItemPosition = -1;
}
public int getCount()
{
return items.length();
}
public Object getItem(int position)
{
return position;
}
public long getItemId(int position)
{
return position;
}
public View getView(int position, View convertView, ViewGroup parent)
{
View view = convertView;
group = parent;
if (view == null)
{
LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = vi.inflate(R.layout.spinner_item, null);
view.setOnTouchListener(this);
}
String itemText = null;
String itemID = null;
try
{
JSONObject jsonObject = items.getJSONObject(position);
itemText = jsonObject.getString(key);
itemID = jsonObject.getString("ID");
}
catch (JSONException e)
{
}
if (itemText != null)
{
TextView name = (TextView) view.findViewById(R.id.spinnerListItemName);
TextView id = (TextView) view.findViewById(R.id.spinnerListItemID);
RadioButton button = (RadioButton) view.findViewById(R.id.spinnerRadioButton);
if (name != null)
name.setText(itemText);
if (id != null)
{
id.setText(itemID);
id.setHint(position + "");
}
if (id.getText().toString().equals(selectedItemID))
{
button.setSelected(true);
button.setChecked(true);
}
else
{
button.setSelected(false);
button.setChecked(false);
}
}
if (selectedItemPosition == -1 && position == 0)
this.setFirstChosen(view);
return view;
}
private void setFirstChosen(View view)
{
RadioButton button = (RadioButton) view.findViewById(R.id.spinnerRadioButton);
button.setSelected(true);
button.setChecked(true);
selectedItemID = ((TextView) view.findViewById(R.id.spinnerListItemID)).getText().toString();
selectedItemPosition = Integer.parseInt(((TextView) view.findViewById(R.id.spinnerListItemID)).getHint().toString());
}
public boolean onTouch(View v, MotionEvent event)
{
RadioButton button = (RadioButton) v.findViewById(R.id.spinnerRadioButton);
if (selectedItemPosition != -1)
{
View previousView = group.getChildAt(selectedItemPosition);
if (previousView != null)
{
RadioButton previous = (RadioButton) previousView.findViewById(R.id.spinnerRadioButton);
previous.setSelected(false);
previous.setChecked(false);
}
}
button.setSelected(true);
button.setChecked(true);
selectedItemID = ((TextView) v.findViewById(R.id.spinnerListItemID)).getText().toString();
selectedItemPosition = Integer.parseInt(((TextView) v.findViewById(R.id.spinnerListItemID)).getHint().toString());
return false;
}
}
There you have it, worked like a charm for me, and i know the pain it is to find information on this subject on-line :)
Another approach is to create your own adapter class, extending BaseAdapter. This would be useful if, for example, there were more than one piece of data you needed for each ListView row.