I'm doing an application for Android and something I need is that it shows a list of all files and directories in the SD Card and it has to be able to move through the different directories. I found a good tutorial in anddev. I modified a few things so the application moves in the SD Card and not in Android root Directories but the rest is mostly the same.
This is my xml file for the activity:
<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@id/android:list"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</ListView>
And this is the code for the Activity:
import hackreatorz.cifrador.R;
import java.io.File;
import java.util.ArrayList;
import android.app.ListActivity;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
public class ArchivosSD extends ListActivity {
private ArrayList<String> directoryEntries = new ArrayList<String>();
private File currentDirectory = new File("/sdcard/");
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
browseToSD();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
private void browseToSD() {
browseTo(new File("/sdcard/"));
}
private void upOneLevel() {
if(this.currentDirectory.getParent() != null)
this.browseTo(this.currentDirectory.getParentFile());
}
private void browseTo(final File directory) {
if (directory.isDirectory()) {
this.currentDirectory = directory;
fill(directory.listFiles());
} else {
Toast.makeText(ArchivosSD.this, this.directoryEntries.get(this.getSelectedItemPosition()), Toast.LENGTH_SHORT).show();
}
}
private void fill(File[] files) {
this.directoryEntries.clear();
this.directoryEntries.add(getString(R.string.current_dir));
if(this.currentDirectory.getParent() != null)
this.directoryEntries.add(getString(R.string.up_one_level));
int currentPathStringLength = (int) this.currentDirectory.getAbsoluteFile().length();
for (File file : files) {
this.directoryEntries.add(file.getAbsolutePath().substring(currentPathStringLength));
}
setListAdapter(new ArrayAdapter<String>(this, R.layout.archivos_sd, this.directoryEntries));
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
int selectionRowID = (int) this.getSelectedItemPosition();
String selectedFileString = this.directoryEntries.get(selectionRowID);
if (selectedFileString.equals(".")) {
this.browseToSD();
} else if(selectedFileString.equals("..")) {
this.upOneLevel();
} else {
File clickedFile = null;
clickedFile = new File(this.currentDirectory.getAbsolutePath() + this.directoryEntries.get(selectionRowID));
if(clickedFile != null)
this.browseTo(clickedFile);
}
}
}
I don't get any errors in Eclipse, but I get a Force Close when running the application on my phone and when I look at Logcat I see the following:
01-01 23:30:29.858: ERROR/AndroidRuntime(14911): FATAL EXCEPTION: main 01-01 23:30:29.858: ERROR/AndroidRuntime(14911): java.lang.UnsupportedOperationException: addView(View, LayoutParams) is not supported in AdapterView
I don't have a clue what to do, I've looked up in Google and I didn't find anything and I did the same at stackoverflow. This is my first aplication in Java and for Android so I'm a real n00b and if the answer was there, I didn't understand it so I would really appreciate if you could explain what I should do to fix this error and why.
Thanks for everything in advance.
For others who have this problem and have inflated a layout in ArrayAdapter
's getView
, set the parent
parameter to null
, as in view = inflater.inflate(R.layout.mylayout, null);
You should always try to pass in a parent while inflating a View, else the framework will not be able to identify what layout params to use for that inflated view.
The correct way of handling the exception is by passing false as third parameter, this flag indicates if a view should be added directly to the passed container or not.
In the case of an adapter, the adapter itself will add the view after you returned the view from you getview
method:
view = inflater.inflate(R.layout.mylayout, parent, **false**);
BaseAdapter sample, comes from just-for-us DevBytes:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View result = convertView;
if (result == null) {
result = mInflater.inflate(R.layout.grid_item, parent, false);
}
// Try to get view cache or create a new one if needed
ViewCache viewCache = (ViewCache) result.getTag();
if (viewCache == null) {
viewCache = new ViewCache(result);
result.setTag(viewCache);
}
// Fetch item
Coupon coupon = getItem(position);
// Bind the data
viewCache.mTitleView.setText(coupon.mTitle);
viewCache.mSubtitleView.setText(coupon.mSubtitle);
viewCache.mImageView.setImageURI(coupon.mImageUri);
return result;
}
CursorAdapter sample:
@Override
public View newView(final Context context, final Cursor cursor, final ViewGroup root) {
return mInflater.inflate(R.layout.list_item_ticket, root, false);
}
More information about view inflation can be found in this article.
When creating an ArrayAdapter like yours, the ArrayAdapter needs a layout resource containing just a TextView. Try changing your ArrayAdapter creation with:
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
this.directoryEntries));
and see if it works.
my problem was this: I override getView in arrayAdapter. then when I inflated view, I forgot to set attach to root to false and that caused this exception.
this is how must be done:
convertView = LayoutInflater.from(getContext()).inflate(R.layout.market_search_product_view, parent,false);
after that problem solved!
https://stacklearn.ir
Delete TextView From ListView in your XML file
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With