简体   繁体   English

自定义ListAdapter中的单击侦听器如何修改列表数据?

[英]How can a click Listener in a custom ListAdapter modify the lists data?

I'm trying to make a relatively simple filesystem browser that displays directories and lets you select them. 我正在尝试制作一个相对简单的文件系统浏览器,用于显示目录并允许您选择它们​​。 I have a list fragment which uses a custom adapter to display the directories as a list. 我有一个列表片段,它使用自定义适配器将目录显示为列表。 I have created a clickListener for each entry in the list. 我已经为列表中的每个条目创建了一个clickListener。 I need to get it so that when a list entry is clicked, the entire list view refreshes. 我需要获取它,以便在单击列表条目时刷新整个列表视图。 As this click listener is defined within my adapter though, how can it signal up the stack somehow to the list fragment, in order to tell it to refresh the data that the adapter uses. 由于此点击侦听器是在我的适配器中定义的,因此它如何以某种方式向堆栈片段发出信号,以便告诉它刷新适配器使用的数据。 Help much appreciated. 帮助非常感谢。

Here is my code: 这是我的代码:

PickerFragment.java: PickerFragment.java:

package com.grid.picker;

import android.content.Intent;
import android.os.Bundle;
//import android.support.v4.app.Fragment;
import android.os.Environment;
import android.support.v4.app.ListFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.List;

import static android.content.Intent.getIntent;

public class PickerFragment extends ListFragment
{
    private String currentFilesystemPath = "";  // This path does not include the root path
    private int numberOfFolders = 0;
    private List<Folder> folders = new ArrayList<Folder>();


    public PickerFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)
    {
        View rootView = inflater.inflate(R.layout.fragment_main, container, false);
        return rootView;
    }

    private void tempPopulate()
    {
        folders.add(new Folder("TestFolder", "/test/path"));
    }

    private void populateFolders()
    {

        // Create a new File at the current path
        File currentFolder = new File(Environment.getExternalStorageDirectory().getPath()+currentFilesystemPath);

        Utility.debugOutput("populateFolders() currentFolder: " +currentFolder);

        // Lets get the list of folders
        String[] directories = currentFolder.list(new FilenameFilter() {
            @Override
            public boolean accept(File current, String name) {
                return new File(current, name).isDirectory();
            }
        });

        // Build up the list of folders with folder objects
        for(int i=0; i<directories.length;i++)
        {
            //Utility.debugOutput("Folder:" +directories[i].toString());
            folders.add(new Folder(directories[i].toString(), currentFolder.getPath()+directories[i].toString()));
        }


    }

    public void onActivityCreated(Bundle savedInstanceState)
    {
        super.onActivityCreated(savedInstanceState);



        // Temporary folder population
        //tempPopulate();
        populateFolders();



        /*
        // Set an adapter for this list fragment to use
        setListAdapter(new ArrayAdapter<Folder>(getActivity(),
                android.R.layout.simple_list_item_activated_1, folders));
        */

        // We want to use our custom adapter. We pass in this activity, the layout to use, and an array of folders
        // We give it a new Folder object just so it knows what type of objects are in the array...??
        FolderAdapter adapter = new FolderAdapter(this.getActivity(), R.layout.listview_item_row, folders.toArray(new Folder[0]));


       // Use our custom adapter for the list
       setListAdapter(adapter);




    }

}

FolderAdapter.java: FolderAdapter.java:

package com.grid.picker;

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.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class FolderAdapter extends ArrayAdapter<Folder>
{
    Folder[] folders = null;
    Context context;
    int layoutResourceId;

    // Constructor
    // Param 1: Reference of the activity
    // Param 2: The resource id of the layout file we want to use for displaying each ListView item
    public FolderAdapter(Context context, int layoutResourceId, Folder[] data)
    {
        super(context, layoutResourceId, data);
        this.layoutResourceId = layoutResourceId;
        this.context = context;
        this.folders = data;
    }

    // This is a function that the click listener can call to start the list update process
    public void updateList(String name)
    {
        Utility.debugOutput("updateList() rx: " +name);


        this.notifyDataSetChanged();


    }

    // Presumably getView is called for every row in the list ?
    // position is the index of the list item in the list
    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        // Create a new view to play with
        View row = convertView;

        final int rowID = position;

        FolderHolder holder = null;

        if(row == null)
        {
            LayoutInflater inflater = ((Activity)context).getLayoutInflater();
            // Inflate (parse) the layout XML
            row = inflater.inflate(layoutResourceId, parent, false);

            //Instantiate a new static object for folder icons (static for speed (caching)
            holder = new FolderHolder();
            holder.imgIcon = (ImageView)row.findViewById(R.id.imgIcon);
            holder.txtTitle = (TextView)row.findViewById(R.id.txtTitle);

            row.setTag(holder);

            // Set clickListener
            row.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v)
                {
                    Utility.debugOutput("Row ID clicked: " +rowID);
                    Utility.debugOutput("Folder array:" +folders[rowID].folderName);
                    updateList(folders[rowID].folderName);
                    //Toast.makeText(context,"you clicked item: "+rowID, Toast.LENGTH_LONG.show();
                    //code you want to execute on click of list item...
                }
            });
        }
        else
        {
            holder = (FolderHolder)row.getTag();
        }

        Folder folder = folders[position];
        holder.txtTitle.setText(folder.folderName);

        holder.txtTitle.setText(folder.folderName);
        holder.imgIcon.setImageResource(folder.icon);

        /*
        // Add click listener to the view
        View.OnClickListener clickListener = new View.OnClickListener() {
            public void onClick(View v) {
                Utility.debugOutput("Something clicked???!");

                // This call requires API level 15 minimum...
                v.callOnClick();
            }
        }; */

        //row.setOnClickListener(clickListener);
        return row;
    }

    // This class will be used as a cache for the folder images
    static class FolderHolder
    {
        ImageView imgIcon;
        TextView txtTitle;
    }
}

Folder.java: Folder.java:

package com.grid.picker;


public class Folder
{
    // Each instance of this class will be an entry in the folder list
    public String folderName;
    public String fullPath;
    public boolean hasChildren = false; // False by default


    public static final int icon = R.drawable.folder;

    // Constructor
    public Folder(String newName, String newFullPath)
    {
        folderName = newName;
        fullPath = newFullPath;
    }


}

listview_item_row.xml: listview_item_row.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="10dp">

    <ImageView android:id="@+id/imgIcon"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:gravity="center_vertical"
        android:layout_alignParentTop="true"
        android:layout_alignParentBottom="true"
        android:layout_marginRight="15dp"
        android:layout_marginTop="5dp"
        android:layout_marginBottom="5dp" />

    <TextView android:id="@+id/txtTitle"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:gravity="center_vertical"
        android:layout_alignParentTop="true"
        android:layout_alignParentBottom="true"
        android:textStyle="bold"
        android:textSize="22dp"
        android:textColor="#000000"
        android:layout_marginTop="5dp"
        android:layout_marginBottom="5dp" />

</LinearLayout>

Eventually I am going to need to put a checkbox on each folder displayed in the list, but for now I need to get it so the folders shown in the list can be clicked on to refresh the display and update the list. 最终,我需要在列表中显示的每个文件夹上放置一个复选框,但是现在我需要获取它,以便可以单击列表中显示的文件夹以刷新显示并更新列表。 Many thanks. 非常感谢。

use this on your click listener 在点击监听器上使用它

// Set clickListener
    row.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v)
        {
            Utility.debugOutput("Row ID clicked: " +rowID);
            Utility.debugOutput("Folder array:" +folders[rowID].folderName);

            notifyDataSetInvalidated();
        }
    });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM