How do I create a working ListView in Android?
I am not looking for you to just fix my code, but am looking for a simple working example of a ListView in Android so I can understand the process of creating one and working with it. But I have included my code so you can see where I am coming from and what I have been trying.
I have done the following and had no success:
--
Made a xml layout with only a TextView item in it:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/dir_text_view"
/>
Created the following class as per the instructions at the following tutorial:
http://www.vogella.com/tutorials/AndroidListView/article.html
public class DataTempleArrayAdapter extends ArrayAdapter<String> {
HashMap<String, Integer> mIdMap = new HashMap<String, Integer>();
public DataTempleArrayAdapter(Context context, int textViewResourceId,
List<String> objects) {
super(context, textViewResourceId, objects);
for (int i = 0; i < objects.size(); ++i) {
mIdMap.put(objects.get(i), i);
}
}
#Override
public long getItemId(int position) {
String item = getItem(position);
return mIdMap.get(item);
}
#Override
public boolean hasStableIds() {
return true;
}
}
And in the main activity I have a snippet of code where I attempt to add a list of strings to the ArrayList associated with the DataTempleArrayAdapter here:
int i;
for (i=0;i<dirContents.length;i++) {
dirList.add(dirContents[i]);
//Toast.makeText(this, dirList.get(i), Toast.LENGTH_SHORT).show();
}
adapter.notifyDataSetChanged();
dirList is successfully populated, while the adapter doesn't update the ListView at all.
--
Before you ask for it, here I am including the rest of the relevant code:
activity_main.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/activity_main"
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="org.hacktivity.datatemple.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="text"
android:hint="#string/directory"
android:ems="10"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:id="#+id/dirEditText" />
<Button
android:text="→"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:id="#+id/dirButton"
android:onClick="populateDirList" />
</LinearLayout>
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:id="#+id/dirListView" />
</LinearLayout>
</RelativeLayout>
And alas the MainActivity class:
public class MainActivity extends AppCompatActivity {
ListView dirListView;
EditText et;
DataTempleArrayAdapter adapter;
ArrayList<String> dirList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dirListView = (ListView) findViewById(R.id.dirListView);
et = (EditText) findViewById(R.id.dirEditText);
dirList = new ArrayList<String>();
dirListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(getApplicationContext(),
"Click ListItem Number " + position, Toast.LENGTH_LONG)
.show();
populateDirList(view);
}
});
ArrayList<String> dirList = new ArrayList<String>();
adapter = new DataTempleArrayAdapter(this,
R.id.dir_text_view, dirList);
dirListView.setAdapter(adapter);
}
public void populateDirList (View view) {
File f;
// NO INPUT.
if (et.getText().toString().equals("")) {
Toast.makeText(this, "empty string", Toast.LENGTH_SHORT).show();
return;
}
f = new File(et.getText().toString());
if (f == null) { return; }
String dirContents[] = f.list();
if (dirContents == null) { return; }
dirList = new ArrayList<String>(Arrays.asList(f.list()));
adapter.clear();
int i;
for (i=0;i<dirContents.length;i++) {
dirList.add(dirContents[i]);
//Toast.makeText(this, dirList.get(i), Toast.LENGTH_SHORT).show();
}
adapter.notifyDataSetChanged();
}
}
One of the best resources for understanding ListView is indeed the
one you mentioned from Vogella
Another cool resource to understand how the the
notifyDataSetChanged() method works in ListView this post from StackOverflow
For a short, simple explanation of how to use CustomLayouts in
ListView (without the ViewHolder pattern) check another of the best
references available: Mkyong
Discussing the benefits of the ViewHolder pattern in ListView:
check this StackOverflow post
Concise example and explanation of the ViewHolder pattern in
ListView: check this example from JavaCodeGeeks
And to fix your code I think the answer given before is only part of the problem:
You must indeed comment the line
//ArrayList<String> dirList = new ArrayList<String>();
because, like #F43nd1r mentioned this would also be a different instance of a list passed into the adapter
but there is more, when you do this:
dirList = new ArrayList<String>(Arrays.asList(f.list()));
you are instantiating a new, different, list, the old reference held by the adapter will NOT be changed... it will still hold the OLD object list
you should perhaps substitute it for something like:
dirList.clear();
dirList.addAll(Arrays.asList(f.list()));
Hope this helps!
Excerpt from your code:
#Override
protected void onCreate(Bundle savedInstanceState) {
//...
dirList = new ArrayList<String>();
//...
ArrayList<String> dirList = new ArrayList<String>();
adapter = new DataTempleArrayAdapter(this,
R.id.dir_text_view, dirList);
//...
}
I bet you already see what the problem is, but in case you don't: You have a field and a local variable with the same name. You pass the local variable to the adapter. It is only naturally that the adapter does not react to changes on the field, as it has no knowledge of its existence.
I think what you have done wrong is to supply a UI Component to the Array Adapter with:
adapter = new DataTempleArrayAdapter(this, R.id.dir_text_view, dirList);
The second item should not be an ID, but a layout file. Android have already implemented a List item layout with a textview that you can use: android.R.layout.simple_list_item_1.
so replace your row with
adapter = new DataTempleArrayAdapter(this, android.R.layout.simple_list_item_1, dirList);
and you are one step closer.
(This way you don't need your "xml layout with only a TextView item in it")
Related
I have the result of a sql query expressed in this way :
//The column attributes of a result table
ArrayList<String> columns_attributes;
// This contains the data of every row of the result
ArrayList<ArrayList<String>> rows_data;
How can i dinamically display it on an activity ? Thanks
MainActivity
public class MainActivity extends AppCompatActivity {
List<String> list = new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list.add("Android");
list.add("iPhone");
list.add("Windows");
list.add("Blackberry");
list.add("Mac");
list.add("Laptop");
list.add("LCD");
list.add("Dell");
ArrayAdapter adapter = new ArrayAdapter<String>(MainActivity.this, R.layout.list_view_item, list);
ListView listView = (ListView) findViewById(R.id.mobile_list);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(MainActivity.this, "Clicked: " + list.get(position), Toast.LENGTH_SHORT).show();
}
});
listView.setAdapter(adapter);
}
}
activity_main.xml
<?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="match_parent"
tools:context="com.vzw.www.listviewalert.MainActivity">
<ListView
android:id="#+id/mobile_list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
list_view_item.xml
<?xml version="1.0" encoding="utf-8"?>
<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" >
</TextView>
You can iterate over these list with simple for loops like this:
// for columns
for (String colAttr : columns_attributes) {
// do something with the string value
}
// for rows
for (List<String> row : rows_data) {
for (String rowAttr : row) {
// do something with the string value
}
}
To display a dynamic amount of data, a ListView is recommended to do the job. If you just want to display those strings, you can use a ListActivity and assign a ArrayAdapter to that ListView with the setListAdapter() method.
You may want to check this tutorial to get this done.
http://androidexample.com/Create_Listview_With_ListActivity_-_Android_Example/index.php?view=article_discription&aid=66
I want to add two buttons in each row of a listview. While using only one Activity means that in my code i have one MainActivity.java and its layout (activity_main.xml) and an additional layout (list_item.xml) which have items in each row (Textviews) but when i add two buttons in a list_item.xml and initialize in MainActivity and add listners on it it shows me an exception which is shared below.Help me to solve my problem, Any sort of help will be highly appreciated.
MainActivity.java
public class MainActivity extends ActionBarActivity
{
String myJSON ;
String id;
private static final String TAG_RESULTS="result";
private static final String TAG_ID = "id";
private static final String TAG_NAME = "name";
private static final String TAG_ADD ="address";
JSONArray peoples = null;
ArrayList <HashMap <String, String> > personList;
ListView list;
TextView quant;
int count=0;
Button b_plus,b_minus;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list = (ListView) findViewById(R.id.listView);
personList = new ArrayList<HashMap<String,String>>();
quant=(TextView)findViewById(R.id.quantity);
b_plus=(Button)findViewById(R.id.ib_plus);
b_minus=(Button)findViewById(R.id.ib_minus);
b_plus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
count++;
quant.setText(Integer.toString(count));
}
});
b_minus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
count--;
quant.setText(Integer.toString(count));
}
});
getData();
}
protected void showList(){
try {
JSONObject jsonObj = new JSONObject(myJSON);
peoples = jsonObj.getJSONArray(TAG_RESULTS);
for(int i=0;i<peoples.length();i++){
JSONObject c = peoples.getJSONObject(i);
id = c.getString(TAG_ID);
String name = c.getString(TAG_NAME);
String address = c.getString(TAG_ADD);
HashMap<String,String> persons = new HashMap<String,String>();
persons.put(TAG_ID,id);
persons.put(TAG_NAME,name);
persons.put(TAG_ADD,address);
personList.add(persons);
}
final ListAdapter adapter = new SimpleAdapter
(
MainActivity.this, personList, R.layout.list_item,
new String[]{TAG_ID,TAG_NAME,TAG_ADD},
new int[]{R.id.id, R.id.name, R.id.address}
);
list.setAdapter(adapter);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
switch(i)
{
case 0 :
Intent appInfo = new Intent(MainActivity.this, MainActivity2.class);
startActivity(appInfo);
break;
case 1 :
Intent ap = new Intent(MainActivity.this, MainActivity3.class);
startActivity(ap);
break;
case 2 :
Intent Info = new Intent(MainActivity.this, MainActivity2.class);
startActivity(Info);
break;
}}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
public void getData(){
class GetDataJSON extends AsyncTask<String, Void, String>{
#Override
protected String doInBackground(String... params) {
DefaultHttpClient httpclient = new DefaultHttpClient(new BasicHttpParams());
HttpPost httppost = new HttpPost("http://10.0.2.2/in.php");
// Depends on your web service
httppost.setHeader("Content-type", "application/json");
InputStream inputStream = null;
String result = null;
try {
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
inputStream = entity.getContent();
// json is UTF-8 by default
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null)
{
sb.append(line + "\n");
}
result = sb.toString();
} catch (Exception e) {
// Oops
}
finally {
try{if(inputStream != null)inputStream.close();}catch(Exception squish){}
}
return result;
}
#Override
protected void onPostExecute(String result){
myJSON=result;
showList();
}
}
GetDataJSON g = new GetDataJSON();
g.execute();
} }
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:orientation="vertical"
android:background="#ff3c3f41"
android:paddingBottom="#dimen/activity_vertical_margin" tools:context=".MainActivity">
<ListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/listView"
/>
</LinearLayout>
list_item.xml
<?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="wrap_content"
android:orientation="vertical"
android:padding="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp" >
<TextView
android:id="#+id/id"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingBottom="2dip"
android:paddingTop="6dip"
android:textColor="#fff9f9f9"
android:textStyle="bold" />
<TextView
android:id="#+id/name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingBottom="2dip"
android:textColor="#fff9f9f9"
android:textStyle="bold"/>
<TextView
android:id="#+id/address"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="left"
android:textColor="#fff9f9f9"
android:textStyle="bold" />
<TextView
android:id="#+id/quantity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="left"
android:textColor="#fff9f9f9"
android:textStyle="bold" />
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="166dp"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp" >
<ImageButton
android:layout_width="58dp"
android:layout_height="52dp"
android:src="#drawable/plus"
android:layout_gravity="start"
android:id="#+id/ib_plus" />
<ImageButton
android:layout_width="58dp"
android:layout_height="52dp"
android:src="#drawable/minus"
android:id="#+id/ib_minus"
android:layout_gravity="center_horizontal"
android:layout_alignBottom="#+id/ib_plus"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignTop="#+id/ib_plus" />
</RelativeLayout>
logcat:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at com.example.abdul.zx.MainActivity.onCreate(MainActivity.java:62)
You'll have to make your adapter more complicated, because there is not one but many buttons and text fields. Pseudo code like solution below. Replace the line where you create your adapter with something like this:
final ListAdapter adapter = new SimpleAdapter
(MainActivity.this, personList, R.layout.list_item,
new String[]{TAG_ID,TAG_NAME,TAG_ADD},
new int[]{R.id.id, R.id.name, R.id.address}) {
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
final TextView quant=(TextView)view.findViewById(R.id.quantity);
final ImageButton b_plus=(ImageButton)view.findViewById(R.id.ib_plus);
final ImageButton b_minus=(ImageButton)view.findViewById(R.id.ib_minus);
b_plus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
count++;
quant.setText(Integer.toString(count));
}
});
b_minus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
count--;
quant.setText(Integer.toString(count));
}
});
return view;
}
};
Remove everything related to quant, b_minus, b_plus from other places in your activity
You need to inflate the list_item layout first as a view. Then, you need to initialize your ImageButtons by view.findViewById(). Now, you are trying to use the ImageButton's of a layout other than what you have set in onCreate. Or another approach would be to set onClick methods inside the adapter.
The problem is that list_item.xml is inflated for each row of data in your ListView. At the point in onCreate() where you try to get the button views, they have not yet been created. In order to set listeners to each button, you need to create a custom adapter class. You will then set the listeners in the getView() method.
Your buttons are not defined in R.layout.activity_main so findViewById will return null since they are not there.
quant is also null, by the way, for the same reason.
You must define your buttons in your SimpleAdapter class because they are in the list_item.xml. (Assuming SimpleAdapter inflates list_item.xml)
I believe that you might be doing these steps in the wrong place:
quant=(TextView)findViewById(R.id.quantity);
b_plus=(Button)findViewById(R.id.ib_plus);
b_minus=(Button)findViewById(R.id.ib_minus);
I think what's happening is that the code is searching for them in activity_main.xml but because they're not there, they end up being null. Hence, the exception you're seeing.
Since the TextView and the Buttons are related to each ListView item, then that's where the initialization should go. I see you're using a SimpleAdaptor which I am not familiar with. But if you create your custom adaptor for ListView, then you can initialize the TextView and the Buttons in the getView() of the Adaptor kind of like this: Custom Adapter for List View.
You can set the button listeners there as well which will provide you with the position of the ListItem where a certain button was clicked.
I am working on an Android application in which I have one container called as Section and there can be Note objects inside it. The use-case is that a user can put multiple notes in a section and organize them. Currently I am to display the section names retrieved from the server with a background image.
Now my problem is how can I display the multiple notes received from the server inside the section.
I understand that this can be achieved by FrameLayout, but a dynamic Note count is what my problem is.
Please note that the count of notes can vary, depending upon user.
Here is the original screenshot of how sections look currently :
Now when you would add notes, it ideally should look like this :
Each of those blocks inside the section contains Note objects. To display its contents, I want to show a note block kind of image and just few words
of the note contents.
Currently I have code to retrieve the Notes from the server, sections can be displayed, but I really have no idea how to proceed because notes can be dynamic. Here is my code so far.
public class GroupSectionActivity extends Activity {
private SectionServiceImpl sectionService = new SectionServiceImpl();
private NoteServiceImpl noteService = new NoteServiceImpl();
private static volatile List<RestSection> restSectionList = new ArrayList<>();
private static volatile List<RestNote> restNoteList = new ArrayList<>();
private static volatile Long groupAccountId;
private static volatile Integer canvasid;
ListView listView;
SectionLazyAdapter sectionLazyAdapter;
static final String msectionname = "msectionname";
static final String msectionid = "msectionid";
Button addSectionButton;
EditText sectionName;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sectionlayout);
Bundle extras = getIntent().getExtras();
if (extras != null) {
groupAccountId = extras.getLong("groupid");
canvasid = extras.getInt("canvasid");
}
restSectionList = this.sectionService.getSectionByCanvas(canvasid);
ArrayList<HashMap<String, String>> restSectionArrayList = new ArrayList<HashMap<String, String>>();
for (RestSection restSection : restSectionList) {
HashMap<String, String> sectionDisplay = new HashMap<>();
sectionDisplay.put("msectionid", String.valueOf(restSection.getMsectionid()));
sectionDisplay.put("msectionname", restSection.getMsectionname());
restSectionArrayList.add(sectionDisplay);
}
listView = (ListView) findViewById(R.id.seclist);
sectionLazyAdapter = new SectionLazyAdapter(this, restSectionArrayList);
listView.setAdapter(sectionLazyAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
int sectionId = restSectionList.get(position).getMsectionid();
Log.d("Sectionid is ", String.valueOf(sectionId));
/*Intent intent = new Intent(GroupSectionActivity.this, GroupSectionActivity.class);
intent.putExtra("groupid", groupAccountId);
intent.putExtra("sectionid", sectionId);
startActivity(intent);
finish();*/
}
});
BaseAdapter to manage the guys :
public class SectionLazyAdapter extends BaseAdapter{
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private static LayoutInflater inflater=null;
public SectionLazyAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
activity = a;
data=d;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
if(convertView==null)
vi = inflater.inflate(R.layout.activity_group_section, null);
TextView sectionName = (TextView)vi.findViewById(R.id.sectionname); // title
// ImageView sectionImage=(ImageView)vi.findViewById(R.id.sectionimage); // thumb image
HashMap<String, String> sectionList = new HashMap<String, String>();
sectionList = data.get(position);
// Setting all values in listview
sectionName.setText(sectionList.get(GroupSectionActivity.msectionname));
return vi;
}
}
activity_group_section.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:orientation="horizontal"
android:padding="5dip" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<FrameLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:weightSum="1">
<ImageView
android:id="#+id/sectionimage"
android:layout_width="wrap_content"
android:layout_height="300dp"
android:scaleType="fitXY"
android:src="#drawable/sectionbackground"
/>
</FrameLayout>
<TextView
android:id="#+id/sectionname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/textView"
android:visibility="visible"
android:gravity="center"
android:layout_gravity="center_horizontal" />
</LinearLayout>
</RelativeLayout>
sectionlayout.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"
tools:context="{relativePackage}.${activityClass}" >
<ListView
android:id="#+id/seclist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/sectionAddButton">
</ListView>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/sectionAddButton"
android:layout_alignParentTop="true"
android:background="#drawable/sectionbackground"
android:text="Add Section" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/sectionNameTextField"
android:layout_alignBottom="#+id/sectionAddButton"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_toEndOf="#+id/sectionAddButton"
android:hint="Section Name"
android:gravity="center"
android:layout_toRightOf="#+id/sectionAddButton" />
</RelativeLayout>
I hope the question is clear, if there is anything missing, kindly let me know.
If you want to display the notes in a dynamic way, you should implement a GridView inside each container, if you set the right margin to each note inside the Grid, the component will dimension itself to fit your section.
The GridView adapter is really simple, works just like the ListView adapter, you will just need to define the number of columns, you can do this in the XML, or programmatically in your Java code.
<GridView
android:id="#+id/grid_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="3"/>
First let me point out that Thomaz is right and you should use a GridView.
It's the right way to go both for your needs and ease of use, but more importantly for it's ability to recycle it's views.
If you won't use any form of view recycling you might get out of memory exception.
But now you face another problem: you want it to be shown in sections.
Why is that a problem? Because:
A) Both the ListView and the GridView do recycling with their child views, and now that each child view of the ListView is a single GridView, which holds inside of it more Views, it's a pretty complex thing to manage. No impossible, but pretty complex.
B) Because of the fact that both the ListView and the GridView are scrollable (and because of that fact are recyclable) there is an issue of scrolling inside scrolling that needs to be resolved.
Luckily I cam across an answer: SuperSLiM (Formally StickyGridHeaders).
This should provide you with an easy solution which suites your needs.
Good luck.
I'm trying to make an audio recorder for which I want to display a list of recordings done till now.
I'm able to get the list recorded files from my SD card in to an ArrayList, but my app crashes when it tries to populate the list view.
ListRecordings.java is called using an Intent from MainActivity.java.
Here is the for ListRecordings.java:
public class ListRecordings extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.listrecordings);
ListView lv;
String path = Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/MyAudioRecorder";
ArrayList<String> FilesInFolder = GetFiles(path);
lv = (ListView) findViewById(R.id.filelist);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.textlayout,
FilesInFolder);
lv.setAdapter(adapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
// Clicking on items
}
});
}
public ArrayList<String> GetFiles(String DirectoryPath) {
ArrayList<String> MyFiles = new ArrayList<String>();
File f = new File(DirectoryPath);
f.mkdirs();
File[] files = f.listFiles();
if (files.length == 0)
return null;
else {
for (int i = 0; i < files.length; i++)
MyFiles.add(files[i].getName());
}
return MyFiles;
}
}
Here's the code for listrecordings.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="#+id/filelist"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
Here's the code for textlayout.xml
<?xml version="1.0" encoding="utf-8"?>
<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="10dp"
android:textSize="16sp"
android:textStyle="bold" >
</TextView>
Any help is appreciated.
I've just started with android so excuse me if i made any lame mistakes.
Thanks
You missing this line in onCreate()
super.onCreate(savedInstanceState);
Add something like this
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.textlayout,
R.id.textview_id_in_textlayout,FilesInFolder);
I hope this will help.
This question already has an answer here:
Android System services not available to Activities before onCreate() [closed]
(1 answer)
Closed 10 years ago.
How could I add items from listView(on my layout) from array?
I tried multiple times, but everytime I get error: System services not avaliable before onCreate.();. Yes, I. know that this er.ror is shown when I try to access ArrayAdapter. Tried almost everything. .Full code is here: pastebin.com/Nv5BkcS7
UPDATE
I followed some other tutorials. My code works now, but there is no data. http://pastebin.com/D8UFKC7i and xml http://pastebin.com/mJfwjGcB
Could someone tell me why it doesn't work.? Debugger says that arrays have all entires
Your onCreate() method is blank in the addcontacts activity, thats the problem:
public class addcontacts extends ListActivity {
protected void onCreate() {
//set content here
setContentView(R.layout.activity_add_contact);
}
...
...
And Don't forget to create activity_add_contact.xml in Layout folder
with content :
<?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="#android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
1.create a custom Adapter exteding BaseAdpter or ArrayAdpter and pass array or ArrayList in constructor.
2.Create the View in layout (of row )
3.inflate this xml in getview function of custom Adapter and set the data.
Activity XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<ListView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/lstText"
/>
</LinearLayout>
list row XML (in layout row.xml)
<?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">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/txtAlertText" />
</LinearLayout>
</LinearLayout>
Create Adapter Class inside your activity
class JSONAdapter extends BaseAdapter implements ListAdapter {
private final Activity activity;
private final JSONArray jsonArray;
private JSONAdapter (Activity activity, JSONArray jsonArray) {
assert activity != null;
assert jsonArray != null;
this.jsonArray = jsonArray;
this.activity = activity;
}
#Override public int getCount() {
if(null==jsonArray)
return 0;
else
return jsonArray.length();
}
#Override public JSONObject getItem(int position) {
if(null==jsonArray) return null;
else
return jsonArray.optJSONObject(position);
}
#Override public long getItemId(int position) {
JSONObject jsonObject = getItem(position);
return jsonObject.optLong("id");
}
#Override public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null)
convertView = activity.getLayoutInflater().inflate(R.layout.row, null);
TextView text =(TextView)convertView.findViewById(R.id.txtAlertText);
JSONObject json_data = getItem(position);
if(null!=json_data ){
String jj=json_data.getString("f_name");
text.setText(jj);
}
return convertView;
}
}
Then add this in your activity.
public class main extends Activity {
/** Called when the activity is first created. */
ListView lstTest;
//Array Adapter that will hold our ArrayList and display the items on the ListView
JSONAdapter jSONAdapter ;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//Initialize ListView
lstTest= (ListView)findViewById(R.id.lstText);
jSONAdapter = new JSONAdapter (main.this,jArray);//jArray is your json array
//Set the above adapter as the adapter of choice for our list
lstTest.setAdapter(jSONAdapter );
}
And you are done.