android - 如何在Drag-Sort ListView中刷新ListView?

标签 android listview android-listfragment

我在我的项目中一起实现了拖放排序 ListView(DSLV) 和 LazyList,我下载了演示 LazyListDrag-Sort ListView从github然后按照我的要求整合修改,

我使用 DSLV 来拖动和排序 ListView 的项目,并使用 LazyList 来显示来自 URL 的图像, 我只是实现了 DSLV 的“基本用法 Playground ”以进行拖动和排序,

我在 TestBedDSLV.java 中实现了搜索,但问题是当我从列表中搜索内容时,我无法更新列表,我尝试了 notifyDataSetChanged 方法但它不起作用,通常我们创建新的适配器并像 lv.setAdapter(adapter) 一样将它传递给 listview,但这里他们只是设置了 ListAdapter,所以我们不能做 lv.setAdapter(adapter)

TestBedDSLV.java

package com.mobeta.android.demodslv;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Menu;
import android.view.MenuInflater;
import android.widget.Button;
import android.widget.EditText;

import com.mobeta.android.dslv.DragSortController;
import com.mobeta.android.dslv.DragSortListView;

public class TestBedDSLV extends FragmentActivity { 

private int mNumHeaders = 0;
private int mNumFooters = 0;

private int mDragStartMode = DragSortController.ON_DOWN;
private boolean mRemoveEnabled = false;
private int mRemoveMode = DragSortController.FLING_RIGHT_REMOVE;
private boolean mSortEnabled = true;
private boolean mDragEnabled = true;

private String mTag = "dslvTag";
Button search;
EditText search_customer;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.test_bed_main);

    search = (Button) findViewById(R.id.btn_search);
    search_customer = (EditText) findViewById(R.id.search_product);

    search_customer.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start, int before,
                int count) {

            // here is logic for refresh the list View
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {

        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    });

    if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction()
                .add(R.id.test_bed, getNewDslvFragment(), mTag).commit();
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.mode_menu, menu);
    return true;
}


private Fragment getNewDslvFragment() {
    DSLVFragmentClicks f = DSLVFragmentClicks.newInstance(mNumHeaders,
            mNumFooters);
    f.removeMode = mRemoveMode;
    f.removeEnabled = mRemoveEnabled;
    f.dragStartMode = mDragStartMode;
    f.sortEnabled = mSortEnabled;
    f.dragEnabled = mDragEnabled;
    return f;
}
}

DSLVFragmentClicks.java

package com.mobeta.android.demodslv;

import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.os.Bundle;
import android.widget.Toast;

public class DSLVFragmentClicks extends DSLVFragment {

public static DSLVFragmentClicks newInstance(int headers, int footers) {
    DSLVFragmentClicks f = new DSLVFragmentClicks();

    Bundle args = new Bundle();
    args.putInt("headers", headers);
    args.putInt("footers", footers);
    f.setArguments(args);

    return f;
}

AdapterView.OnItemLongClickListener mLongClickListener = 
        new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2,
                    long arg3) {
                String message = String.format("Long-clicked item %d", arg2);
                Toast.makeText(getActivity(), message, Toast.LENGTH_SHORT).show();
                return true;
            }
        };

@Override
public void onActivityCreated(Bundle savedState) {
    super.onActivityCreated(savedState);

    ListView lv = getListView();
    lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                long arg3) {
            String message = String.format("Clicked item %d", arg2);
            Toast.makeText(getActivity(), message, Toast.LENGTH_SHORT).show();

        }
    });
    lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
        @Override
        public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2,
                long arg3) {
            String message = String.format("Long-clicked item %d", arg2);
            Toast.makeText(getActivity(), message, Toast.LENGTH_SHORT).show();
            return true;
        }
    });
}
}

DSLV fragment .java

package com.mobeta.android.demodslv;

import java.util.ArrayList;
import java.util.Arrays;

import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;

import com.mobeta.android.dslv.DragSortController;
import com.mobeta.android.dslv.DragSortListView;

public class DSLVFragment extends ListFragment {

ArrayAdapter<String> adapter;

private String[] array;
public static ArrayList<String> list;

private DragSortListView.DropListener onDrop = new DragSortListView.DropListener() {
    @Override
    public void drop(int from, int to) {
        if (from != to) {
            String item = adapter.getItem(from);
            adapter.remove(item);
            adapter.insert(item, to);
        }
    }
};

private DragSortListView.RemoveListener onRemove = new DragSortListView.RemoveListener() {
    @Override
    public void remove(int which) {
        adapter.remove(adapter.getItem(which));
    }
};

protected int getLayout() {
    return R.layout.dslv_fragment_main;
}

/**
 * Return list item layout resource passed to the ArrayAdapter.
 */
protected int getItemLayout() {
    return R.layout.list_item_handle_right;

}

private DragSortListView mDslv;
private DragSortController mController;

public int dragStartMode = DragSortController.ON_DOWN;
public boolean removeEnabled = false;
public int removeMode = DragSortController.FLING_RIGHT_REMOVE;
public boolean sortEnabled = true;
public boolean dragEnabled = true;

public static DSLVFragment newInstance(int headers, int footers) {
    DSLVFragment f = new DSLVFragment();

    Bundle args = new Bundle();
    args.putInt("headers", headers);
    args.putInt("footers", footers);
    f.setArguments(args);

    return f;
}

public DragSortController getController() {
    return mController;
}

/**
 * Called from DSLVFragment.onActivityCreated(). Override to set a different
 * adapter.
 */
public void setListAdapter() {
    array = getResources().getStringArray(R.array.jazz_artist_names);
    list = new ArrayList<String>(Arrays.asList(array));

    adapter = new ArrayAdapter<String>(getActivity(), getItemLayout(),
            R.id.text, list);
    setListAdapter(adapter);
}

/**
 * Called in onCreateView. Override this to provide a custom
 * DragSortController.
 */
public DragSortController buildController(DragSortListView dslv) {
    DragSortController controller = new DragSortController(dslv);
    controller.setDragHandleId(R.id.drag_handle);
    controller.setClickRemoveId(R.id.click_remove);
    controller.setRemoveEnabled(removeEnabled);
    controller.setSortEnabled(sortEnabled);
    controller.setDragInitMode(dragStartMode);
    controller.setRemoveMode(removeMode);
    return controller;
}

/** Called when the activity is first created. */
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    mDslv = (DragSortListView) inflater.inflate(getLayout(), container,
            false);

    mController = buildController(mDslv);
    mDslv.setFloatViewManager(mController);
    mDslv.setOnTouchListener(mController);
    mDslv.setDragEnabled(dragEnabled);

    return mDslv;
}

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

    mDslv = (DragSortListView) getListView();

    mDslv.setDropListener(onDrop);
    mDslv.setRemoveListener(onRemove);

    Bundle args = getArguments();
    int headers = 0;
    int footers = 0;
    if (args != null) {
        headers = args.getInt("headers", 0);
        footers = args.getInt("footers", 0);
    }
    setListAdapter();
}
}

test_bed_main.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"
android:orientation="vertical" >

<LinearLayout
    android:id="@+id/search_lay"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:orientation="horizontal" >

    <EditText
        android:id="@+id/search_product"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="2dp"
        android:layout_marginLeft="5dp"
        android:layout_marginTop="2dp"
        android:layout_weight="1"
        android:background="@drawable/search_back"
        android:hint="Enter Firstname"
        android:imeOptions="actionSearch"
        android:inputType="text"
        android:paddingBottom="2dp"
        android:paddingLeft="5dp"
        android:paddingTop="2dp"
        android:visibility="visible" />

    <Button
        android:id="@+id/btn_search"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:layout_weight="2.5"
        android:text="CANCEL"
        android:textColor="#155280"
        android:textSize="14sp"
        android:textStyle="bold"
        android:visibility="visible" />
</LinearLayout>

<FrameLayout
    android:id="@+id/test_bed"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" />
<!-- We will add the DSLVFragment inside the FrameLayout in code -->

</LinearLayout>

enter image description here

和其他需要的类可以从我上面给出的github链接下载.....

最佳答案

实际上,如果您仔细查看代码,就会发现您提到了一种方法

public void setListAdapter() {
    array = getResources().getStringArray(R.array.jazz_artist_names);
    list = new ArrayList<String>(Arrays.asList(array));

    adapter = new ArrayAdapter<String>(getActivity(), getItemLayout(),
            R.id.text, list);
    setListAdapter(adapter);
}

正如你所说: “通常我们创建新的适配器并将其传递给 ListView ,如 lv.setAdapter(adapter) ,但这里他们只是设置 ListAdapter,所以我们不能做 lv.setAdapter(adapter)”

你不能通过根据你的搜索轻松生成一个数组并像代码一样设置它来轻松做到这一点吗??

list = new ArrayList<String>(Arrays.asList(array));

        adapter = new ArrayAdapter<String>(getActivity(), getItemLayout(),
                R.id.text, list);
        setListAdapter(adapter);

编辑:我认为您问错了问题。您主要关心的应该是如何在 Activity 和 fragment 之间进行通信……因为您的搜索功能处于 Activity 状态而列表处于 fragment 状态。因此,您需要设置一个接口(interface),基本上将搜索字符串传递给您的 fragment ,然后您可以创建一个数组并按照与现在相同的方式进行设置。

阅读this所以问答。在答案中,您会发现一种在 Activity 和 fragment 之间传递数据的类似方法。

编辑 2:您主要关心的是从 Activity 到 Fragment 的通信。在您的 Activity 中声明一个接口(interface),如下所示:

    public interface FragmentCommunicator{
       public void passDataToFragment(String someValue);
    }

then call the interface at your text change listener..for example

    FragmentCommunicator mfragmentCommunicator;
    //your onCreate function 
    {
    //your textchangelistenr
    {
    onTextChanged call 
if(mfragmentCommunicator != null)
   mfragmentCommunicator.passDataToFragment(Pass your string here)
    }

then make your fragement implement this interface like

public class someFragment extends Fragment implements FragmentCommunicator
{
//this is your rest of the fragment

@Override
public void passDataToFragment(String somevalue)
{
//This function will get fired each time your text is changed since in your activity you are calling this same function in your textchange listener. the String somevalue will be the string that you passed from your activity


}

//rest of the code
.
.
.
//Don't forget to initialize your interface in fragment itself. Do this in your onAttach
like this
@Override
 public void onAttach(Activity activity){
  super.onAttach(activity);
  context = getActivity();

  ((MainActivity)context).fragmentCommunicator = this;
}

}

}

可以引用this任何进一步说明的链接。只检查 FragmentCommunicator 的实现

关于android - 如何在Drag-Sort ListView中刷新ListView?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15893550/

相关文章:

android - Curser 适配器中的 notifyDataSetChanged 不适用于 listfragment

java - 如何修复 "Can' t 通过此策略定位元素 : Locator map:"

android - 对于 ListView 适配器,如何调用 getView()?

android - 国家和 ISD(调用)代码列表作为 android 微调器的两个数组

java - Android ListView : how to use fast scrolling and alphabetical ordering

ASP.NET 将整数绑定(bind)到 CheckBox 的 Checked 字段

android - 未调用适配器中的 ListFragment 未呈现和 getView()

java - ListView - 通过滚动加载更多项目

java - 尝试加载显然存在的库时出现 UnsatisfiedLinkError

Android Google Maps API V2.0 - 在 XML 中包含 MapView