单击一个项目时更新Alert Fragment中的列表视图

时间:2014-11-15 21:11:16

标签: android listview android-alertdialog

我希望有一个像文件浏览器一样工作的AlertDailog。我显示文件/目录列表,当用户点击一个文件夹时,我想在同一个AlertDialog中显示其内容。我想刷新AlertDialog而不是解雇并创建一个新的。

我已经尝试了几项检查其他问题,但我仍然无法做到。

这是我的DialogFragment

public class FileExplorer extends DialogFragment implements AdapterView.OnItemClickListener{

    private View view;

    private static final String TAG = "FileExplorer";
    private static String extensionFilter;
    private static File path;

    private Item[] fileList;    

    AlertDialog.Builder builder;
    ListFileAdapter myAdapter;


    /**
     * Empty constructor required for DialogFragment 
     */
    public FileExplorer (){
    }

    public static FileExplorer newInstance(String filePath, String fileFilter ) {     

        //stores in path the directory (if input). If not, it is the root directory
        if (filePath!=null && !filePath.equals("")) {
            path = new File(filePath);
            if (path.isFile()){
                path = path.getParentFile();
            }
        } else {
            path = new File(Environment.getExternalStorageDirectory() + "");
        }

        if (fileFilter==null){
            extensionFilter = "";
        }
        else {
            extensionFilter = fileFilter;
        }

        //Bundle args = new Bundle();
        //args.putSerializable("path", path);
        //args.putSerializable("filter", extensionFilter);

        FileExplorer fragment = new FileExplorer();
        //fragment.setArguments(args);

        return fragment;
    }


    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState){    

        view = getActivity().getLayoutInflater().inflate(R.layout.activity_file_explorer, null);

        //fill the fileList with all the files and folders in the directory
        loadFileList();      
        myAdapter = new ListFileAdapter(getActivity(), fileList); 

        ListView fileListView = (ListView)view.findViewById(R.id.list);
        fileListView.setAdapter(myAdapter);
        fileListView.setOnItemClickListener(this);

        builder = new AlertDialog.Builder(getActivity());
        builder.setView(view);
        return builder.create();
    }

    @Override
    /**
     * 
     * adapterView: is the list view that was clicked
     * view: the row that was clicked
     * position: position of the row
     * id: id of the textview assigned by the system
     * 
     */
    public void onItemClick(AdapterView<?> adapterView,  View view, int position, long id){

        Toast.makeText(adapterView.getContext(), adapterView.getItemAtPosition(position).toString(), Toast.LENGTH_SHORT).show();

        if (adapterView.getItemAtPosition(position).toString().equals("..")){
            path = path.getParentFile();
        } else {
            path = new File(path.getPath() + "/" + adapterView.getItemAtPosition(position).toString());
        }


        loadFileList();
        myAdapter.notifyDataSetChanged();
    }
}

这是我的ListFileAdapter:

package com.cropwatuco.adapters;

import com.cropwatuco.general.FileExplorer.Item;
import com.cropwatuco.R;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;


public class ListFileAdapter extends BaseAdapter {

    private Item[] list;
    private Context context;
    private static LayoutInflater inflater = null;

    public ListFileAdapter(Context context, Item[] list) {
        super();
        this.list = list;
        this.context = context;
        // Layout inflator to call external xml layout ()
        inflater = (LayoutInflater) this.context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    /**
     * Abstract method from BaseAdapter
     * Returns the total number of rows the list will have
     */
    public int getCount() {
        return list.length;
    }

    @Override
    /**
     * Abstract method from BaseAdapter
     * Returns the data model for a given position, passed in as the typical int index
     */
    public Object getItem(int position) {
        return list[position];
    }

    @Override
    /**
     * Abstract method from BaseAdapter
     * Returns a unique long value for a given position. As I dont have any, I return the position
     */
    public long getItemId(int position) {
        return position;
    }

    @Override
    /**
     * Abstract method from BaseAdapter
     * Returns the View to use for a given row
     * 
     * position: position in the list
     * convertView: view that is reused (in case it is not null)
     * parent: parent view
     * 
     * return: the convertView modified or a new view
     */
    public View getView(int position, View convertView, ViewGroup parent) {

        View row = convertView;

        // check if the row to recycle is not null
        // if it is, a new one has to be created
        // if not, it has to be recycled
        if (row == null) {
            row = inflater.inflate(R.layout.row_list, parent, false);
        }

        // get the access to the view elements of a row
        // if it is a new row, it has to be created
        // if not, the reference to the views are already created
        ViewHolder holder = (ViewHolder) row.getTag();
        if (holder == null) {
            holder = new ViewHolder(row);
            row.setTag(holder);
        }

        String filename = ((Item) getItem(position)).getString();
        holder.label.setText(filename);

        if (((Item) getItem(position)).getIsDirectory()) {
            holder.icon.setImageResource(R.drawable.ic_folder);
        } else {
            holder.icon.setImageResource(R.drawable.ic_file);
        }

        return row;

    }


    class ViewHolder {

        ImageView icon = null;
        TextView label = null;

        ViewHolder(View row) {
            this.icon = (ImageView) row.findViewById(R.id.icon);
            this.label = (TextView) row.findViewById(R.id.label);
        }
    }

}

最后,我的activity_file_explorer.xml

<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/list"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#EEEEEE" />

这不会使用新内容更新列表视图。

如果我在myAdapter.notifyDataSetChanged()之后添加builder.show();程序崩溃了这个堆栈:

11-15 20:58:15.170: E/InputEventReceiver(780): Exception dispatching input event.
11-15 20:58:15.170: E/MessageQueue-JNI(780): Exception in MessageQueue callback: handleReceiveCallback
11-15 20:58:15.287: E/MessageQueue-JNI(780): java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.view.ViewGroup.addViewInner(ViewGroup.java:3339)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.view.ViewGroup.addView(ViewGroup.java:3210)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.view.ViewGroup.addView(ViewGroup.java:3186)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at com.android.internal.app.AlertController.setupView(AlertController.java:413)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at com.android.internal.app.AlertController.installContent(AlertController.java:241)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.app.AlertDialog.onCreate(AlertDialog.java:337)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.app.Dialog.dispatchOnCreate(Dialog.java:355)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.app.Dialog.show(Dialog.java:260)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.app.AlertDialog$Builder.show(AlertDialog.java:951)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at com.cropwatuco.general.FileExplorer.onItemClick(FileExplorer.java:109)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.widget.AdapterView.performItemClick(AdapterView.java:298)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.widget.AbsListView.performItemClick(AbsListView.java:1100)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.widget.AbsListView$PerformClick.run(AbsListView.java:2749)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.widget.AbsListView.onTouchEvent(AbsListView.java:3435)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.view.View.dispatchTouchEvent(View.java:7246)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2168)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1903)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1953)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1405)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.app.Dialog.dispatchTouchEvent(Dialog.java:740)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1901)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.view.View.dispatchPointerEvent(View.java:7426)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3220)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3165)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4292)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4271)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4363)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:179)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.os.MessageQueue.nativePollOnce(Native Method)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.os.MessageQueue.next(MessageQueue.java:125)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.os.Looper.loop(Looper.java:124)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at android.app.ActivityThread.main(ActivityThread.java:5041)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at java.lang.reflect.Method.invokeNative(Native Method)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at java.lang.reflect.Method.invoke(Method.java:511)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
11-15 20:58:15.287: E/MessageQueue-JNI(780):    at dalvik.system.NativeStart.main(Native Method)

但我不知道要删除的内容和位置。

我会感激任何帮助,因为我已经坚持了一个多星期:(

1 个答案:

答案 0 :(得分:0)

您似乎在本地加载新文件列表,而您的适配器包含旧项目。

快速解决方案是将适配器内的项目公开,以便您可以操作它们:

public class ListFileAdapter extends BaseAdapter {
    public Item[] list;
    ...
}

然后更新监听器内的项目:

public void onItemClick(AdapterView<?> adapterV,  View v, int pos, long id) {
    ...
    loadFileList();
    myAdapter.list = fileList;
    myAdapter.notifyDataSetChanged();
}

您当然不必在点击监听器中调用builder.show,因为单击某个项目时已显示该对话框。