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

Posted

技术标签:

【中文标题】如何在 Drag-Sort ListView 中刷新 ListView?【英文标题】:How to refresh the ListView in Drag-Sort ListView? 【发布时间】:2013-03-31 09:18:33 【问题描述】:

我在我的项目中同时实现了 Drag-Sort ListView(DSLV) 和 LazyList,我从 github 下载了 Demo LazyList 和 Drag-Sort ListView 然后根据我的要求进行集成和修改,

我使用 DSLV 对 ListView 和 LazyList 的项目进行拖动和排序以从 URL 显示图像, 我只是从 DSLV 实现“基本用法游乐场”进行拖动和排序,

我在 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;
        
    );


DSLVFragment.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_
android:layout_
android:orientation="vertical" >

<LinearLayout
    android:id="@+id/search_lay"
    android:layout_
    android:layout_
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:orientation="horizontal" >

    <EditText
        android:id="@+id/search_product"
        android:layout_
        android:layout_
        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_
        android:layout_
        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_
    android:layout_ />
<!-- We will add the DSLVFragment inside the FrameLayout in code -->

</LinearLayout>

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

【问题讨论】:

您粘贴了太多代码。您为什么不尝试将范围缩小到重要的行。 “说话很便宜。给我看看代码。” 我已经发布了代码请检查它.... 有些时候如果你不初始化 ArrayList 那么它会产生空指针异常。你应该先初始化 ArrayList。 【参考方案1】:

实际上,如果您仔细查看您的代码,那么您已经提到了一个方法

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);

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

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

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

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

编辑:我认为你问错了问题。您主要关心的是如何在活动和片段之间进行通信......因为您的搜索功能在活动中并且列表在片段中。因此,您需要设置一个接口,该接口基本上将搜索字符串传递给您的片段,您可以在其中创建一个数组并按照您现在所做的相同方式设置它。

阅读this SO问答。在答案中,您会发现一种在活动和片段之间传递数据的类似方法。

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

    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 的实现

【讨论】:

我已经尝试了很多次,但它不能工作.....让我知道我从哪里设置的??我在 TestBedDSLV.java 文件中实现了搜索,我必须从 TestBedDSLV.java 设置它,我已经做了很多次但它不能工作....我认为这个 setListAdapter 只能在 DSLV 中设置一次 setListAdapter 之所以存在,是因为该类扩展了 ListFragment。如果将其扩展到片段,则可以使用 setadapter。没有区别。无论如何,您始终可以在 Activity 和 Fragment 之间创建一个接口,以直接在 Fragment 本身中刷新您的视图。 我刚刚读到这个问题,当这个 getData() 方法被调用时,只有在活动开始时?搜索时如何发送数据?? 您只有一个片段还是要添加多个片段? 让我们continue this discussion in chat【参考方案2】:

如果您使用数组作为适配器的基本数组列表,只需更新此数组并调用 adapater.notifyDataSetChanged()。这肯定会更新 DSLV,因为我在我的一个项目中使用了相同的方法。

【讨论】:

兄弟我试过很多次,但它对我不起作用......这不是一个小问题......

以上是关于如何在 Drag-Sort ListView 中刷新 ListView?的主要内容,如果未能解决你的问题,请参考以下文章

在 vega 中刷/链接(不是 vega-lite)

神器!在IDE中刷LeetCode,刷题效率直线up!

神器!在IDE中刷LeetCode,刷题效率直线up!

在IDE中刷LeetCode,编码调试一体化,刷题效率直线up!

从 Android 中最近的应用程序中刷出应用程序时服务停止

开发板刷系统---利用fastboot向iNand中刷入镜像