Add items to ListView Android - java

I have an app that gets all the .mp3 files off of a storage device and I want to add them to a ListView when the app is created. I am lost on adding items to the list. I have googled it and I cannot a good defintion of what the dev is going and why they are adding what they are adding. I would like someone to tell me how to add items to a ListView and also, if they can, explain what they are doing as they are doing it so I understand and learn from it. I am a new Android Dev and looking to learn as much as I can and not just fix my code.
So, my current code is...
XML
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/ListView"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
and I do not know what to do on my main activity. I so far have...
File storageDir = new File("/mnt/extSdCard/");
ArrayList<String> listItems=new ArrayList<String>();
ArrayAdapter<String> adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
walkdir(storageDir);
}
public void walkdir(File directory) {
TextView songList=(TextView)findViewById(R.id.textView);
String fileType = ".mp3";
File[] listFile = directory.listFiles();
if (listFile != null) {
for (int i = 0; i < listFile.length; i++) {
if (listFile[i].isDirectory()) {
walkdir(listFile[i]);
} else {
if (listFile[i].getName().endsWith(fileType)){
//I need to add the items to the ListView right here.
//listFile[i].toString() is the code to get the text, aka what i want to add
}
}
}
} }

To start with, in your activity, you should extend ListActivity instead of Activity. This will give you access to a method called setListAdapter (there are other ways, but this is probably easiest).
The setListAdapter method takes an adapter as its parameter, so we now need to create an adapter that we can pass it.
To do so, write the following:
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
listFile);
I'll break that down a little bit:
The first part (this) is where we pass it the context.
The second part is the layout file that represents each individual list item. To save us having to create one, we are using one that android has built in.
Finally, we need to pass it the words you want it to display (in your case, a string array, although it could also be an ArrayList of strings.
Once you've done that, we just need to pass the adapter to our setListAdapter method, like so
setListAdapter(adapter);
But before you run your code, we need to add one little line to the XML file. When you extend ListActivity, Android will be looking for a list whose id is android.R.id.list, so we need to set the id like so:
<ListView
android:id="#android:id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />

initialize your list adapter after fetching mp3 file names.
adapter = new ArrayAdapter(yourContext,android.R.layout.simple_list_item_1,yourFileNameList);
Looking at your code you are trying to convert the mp3 file to string and showing in listview. You can just show the filename.

You need to set adapter for the custom listview you have built.
Go to youtube and search for videos by Slidenerd. He has all the basic tutorials for android. The listview tutorials start from #77.

Related

Creating numerous LIstViews or TableLayouts programatically

I have read various posts on programmatically creating a TableLayout/ListView and I'm still unsure of the best route to take.
In my mind I have one class called RunTests.java. One test schedule can contain numerous test types, and for each test type a table of results is required. So let's say there are four tests, named A, B, C and D.
After test A has completed I'd ideally like to call another class (ProcessTable.java) and pass it an array of test results, and array of test column headings and an array of test row headings. The class would then return a table, complete with results and headings, and inflate it so it becomes visible within an XML LinearLayout, and then move on to test B.
The process would then repeat and the next table would appear below the first one, and so on.
Any advice or examples would be great.
Thanks
Attempt at suggested answer:
I'm getting an error on listView, I'm not sure where I define this. The XML I've added to be existing layout is below:
private void createTable() {
String[] columns = {"row_header", "column_name1", "column_name2"};
String[] results = {"","2000","98"};
int[] to = { R.id.row_header, R.id.txt1 ,R.id.txt2};
String[] rowHeadings = {"","Bandwidth","QoS"};
List<HashMap<String, String>> data = new ArrayList<HashMap<String, String>>();
for(int i = 0; i < rowHeadings.length; i++){
HashMap<String, String> map = new HashMap<String, String>();
map.put(columns[0], rowHeadings[i].toString());
map.put(columns[1], results[1]);
map.put(columns[2], results[2]);
data .add(map);
}
SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), data, R.layout.runtests, columns, to);
listView.setAdapter(adapter);
}
XML:
<LinearLayout android:id="#+id/resultsLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center|top"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:background="#drawable/curvedbg"
android:layout_marginTop="10dp"
android:padding="5dp"
android:weightSum="99">
<TextView android:id="#+id/row_header" android:layout_weight="33" />
<TextView android:id="#+id/txt1" android:layout_weight="33"/>
<TextView android:id="#+id/txt2" android:layout_weight="33"/>
</LinearLayout>
My gut tells me you should be using a ListView. This will cater well to generating Views on the fly for varying data types. Also, if you have a rather large list of results that can't fit onto the screen, The ListView will auto handle scrolling and will only maintain in memory the data that displays to the screen.
On the other hand you'll need to wrap the TableLayout with a ScrollView and it will maintain all Views generated in memory...whether or not they are shown on the screen. You'll also need to setup a lot of boiler plate code just to get Views generated and attached to the main XML. In short, TableLayout would be great for static data.
Going with the ListView approach, it sounds like you should be using a SimpleAdapter. Not to terribly common as they are only useful for certain situations. Honestly the name should be ListMapAdapter as that's how it stores and expects data to be passed to it...via a List of Maps and it can be more difficult to use then an ArrayAdapter because it has one of the most confusing constructors ever. Basically the SimpleAdapter is great for rendering table like layouts, where you have columns of data.
Here's a basic example to give you an idea of how to use. This works for displaying Strings of data directly to a TextView.
//Columns is used to assign a column to a TextView. So columns[1] will place all data
//found in column 1 into to[1]...which is the TextView R.id.txt1. Columns is also used
//to map which data item belongs to a particular column
String[] columns = {"row_header", "column_name1", "column_name2", "column_name3"}
int[] to = { R.id.row_header, R.id.txt1 ,R.id.txt2, R.id.txt3};
//This is where you will assemble the test data. Probably the most difficult part
//as you must convert your test results into a List of Maps. Each index in the
//List represents a row of data. The Map represents all the columns of data for
//that row.
List<HashMap<String, String>> data = new ArrayList<HashMap<String, String>>();
for(int i = 0; i < rowHeadings.size(); i++){
HashMap<String, String> map = new HashMap<String, String>();
map.put(columns[0], rowHeadings.get(i));
map.put(columns[1], Your_data_for_column1);
map.put(columns[2], Your_data_for_column2);
map.put(columns[3], Your_data_for_column3);
data .add(map);
}
SimpleAdapter adapter = new SimpleAdapter(getContext(), data, R.layout.list_layout, columns, to);
listView.setAdapter(adapter);
Higher Overview Example of list_layout.xml
<LinearLayout>
<TextView android:id="#+id/row_header"/>
<TextView android:id="#+id/txt1"/>
<TextView android:id="#+id/txt2"/>
<TextView android:id="#+id/txt3"/>
</LinearLayout>
Note whether or not the SimpleAdapter works for your data is more detail dependent. Using an ArrayAdapter, CursorAdapter, etc is just as viable. It all boils down to how your data is organized. Also, if you need to display your data in a more complex way then just Strings...you may need to override the adapters' getView()...and if thats the case, definitely be sure to use the adapter whose data organization best matches yours.

How to populate an android spinner with a java String array

I am new to Android and working on a "project" as a teaching method.
I added a spinner on the UI
<Spinner
android:id="#+id/spinner1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="38dp" />
and i am trying to pass on the values from a String Array
String[] branchesArray = st.split(";");
I have been looking around the web for this one, but i just cant make it to work.
The most popular seems to be something like that
ArrayAdapter<String> adapter0 = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, branchesArray);
which is giving me this error
The constructor ArrayAdapter(MainActivity.getData, int, String[]) is undefined
and, according to an other post using this
ArrayAdapter<String> adapter0 = new ArrayAdapter<String>
(Activity.this, android.R.layout.simple_spinner_item, branchesArray);
gives me this error
No enclosing instance of the type Activity is accessible in scope
Any help is highly appreciated.
Activity is a class. If you want to reference your current class just use this or perhaps MainActivity.this.

custom rows in ListView

i have the following problem, I am writing an app that repeats the http://www.rottentomatoes.com/mobile/ website, if you look on the site there are deviders the "Opening this Week", "Top Box Office" and "Also in Theaters" so my question is, how do i add this custom rows to the ListView that holds all the movies
here is what i have so far, please pitch me some ideas so it will look exactly like on the site
The easiest way to achieve this would be to include the dividers in the layout of item views. Then make them VISIBLE only when the view maps to the first item of a new category, otherwise leave them as GONE.
Example (in semi-pseudocode):
First, make your item layout like this:
<LinearLayout orientation=vertical>
<TextView id=divider>
<your original item layout>
</LinearLayhout>
Then, in the adapter's getView():
Film item = getItem(position);
boolean needsDivider = (position == 0 || getItem(position - 1).filmCategory != film.filmCategory);
if (needsDivider)
{
dividerView.setVisibility(View.VISIBLE);
dividerView.setText(getFilmCategoryName(film.filmCategory));
}
else
dividerView.setVisibility(View.GONE);
A more fancy solution would be to use a library like StickyListHeaders. It doesn't work as your mobile site example, but it's probably even better (e.g. the headers don't scroll up out of the screen).

NullPointerException when acting on a View

For some reason I'm getting a nullPointerException when working with any new View I place in my XML. The view type (TextView, EditText, etc) doesn't matter. Any views I originally had work - it's isolated to any newly added views.
I've tried cleaning the project numerous times, deleted the entire XML file, restarted eclipse, then re-pasted the XML back into a new file, no luck. Appears to be similar as this question, but nothing has gotten this working.
I really don't want to have to re-create the entire project, but I'm not sure what else to do if recreating the XML and cleaning isn't enough.
Code is as follows:
XML
...
<TextView
android:id="#+id/dlg_add_proj_test_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Test Text" />
...
Activity
...
public void fireDlg() {
final Dialog dialog = new Dialog(this);
dialog.setContentView(R.layout.dialog_add_proj);
dialog.setTitle("Add Project");
//Other previous views
TextView newTxtView = (TextView) findViewById(R.id.dlg_add_proj_test_text);
newTxtView.setText("New Text"); //Null Pointer Here
}
...
you should be using dialog.findViewById(R.id.dlg_add_proj_test_text) instead of just findViewById. The findViewById uses the activity's method while dialog.findViewById uses the method in the dialog.

Spinner not a view that can be bounds(sp) by this SimpleCursorAdapter

I'm trying to adapt my query to my spinner object with some trouble, I get the error listed as the title. Here is the code portion where it crashes:
Spinner classDropDown = (Spinner) this.findViewById(R.id.classDropDown);
int[] to = new int[] { R.id.classDropDown };
String[] classFields = new String[] { "className" };
SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter(this, R.layout.main, cursor, classFields, to);
cursorAdapter.setDropDownViewResource(R.id.classDropDown);
classDropDown.setAdapter(cursorAdapter);
I had a problem where the cursor wasn't being filled but fixed that now. Can someone give me help on debugging this issue?
Edit: I think my problem is the "to" field. What should this be?
Edit 2: Also, here is the XML for the spinner object:
<Spinner
android:id="#+id/classDropDown"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Edit 3: I've fixed the above to reflect fixing the code. This fixes this particular problem. I'm not getting the error, but I also have nothing displayed in the spinner.
To is a list of resource ids that you want to put your data into, such as R.id.textview1, and they meed to be contained in the layout you specify in the adapter. The number of elements should also match the number of elements in your from array ( you called it classfields).
So, you have two pieces of data and only specified one target resource id. Either remove one of the fields in your classfields array or add a widget to your layout and call.it in your to array and it should work.

Categories