Android DynamicListView项目在拖动时消失(&;滴

Android DynamicListView项目在拖动时消失(&;滴,android,android-listview,drag-and-drop,Android,Android Listview,Drag And Drop,我遵循这个google教程,实现了一个用于拖放的动态ListView 它会显示listview中的所有项目,但当我拖放元素时,它们会消失 如果我在设置适配器之前添加元素listView.setAdapter(适配器)它工作完全正常 库源代码 我该如何解决这个问题 更新 StableArrayAdapter.java package com.example.android.navigationdrawerexample; import android.content.Context; impo

我遵循这个google教程,实现了一个用于拖放的动态ListView

它会显示listview中的所有项目,但当我拖放元素时,它们会消失

如果我在设置适配器之前添加元素
listView.setAdapter(适配器)它工作完全正常

库源代码

我该如何解决这个问题

更新

StableArrayAdapter.java

package com.example.android.navigationdrawerexample;

import android.content.Context;
import android.widget.ArrayAdapter;

import java.util.HashMap;
import java.util.List;

public class StableArrayAdapter extends ArrayAdapter<String> {

    final int INVALID_ID = -1;

    int mRowLayout;
    List<String[]> mStrings;
    HashMap<String, Integer> mIdMap = new HashMap<String, Integer>();

    // constructor
    public StableArrayAdapter(Context context, int rowLayout, List<String> objects) {
        super(context, rowLayout, objects);
        for (int i = 0; i < objects.size(); ++i) {
            mIdMap.put(objects.get(i), i);
        }
    }

    @Override
    public long getItemId(int position) {
        if (position < 0 || position >= mIdMap.size()) {
            return INVALID_ID;
        }
        String item = getItem(position);
        return mIdMap.get(item);
    }

    @Override
    public boolean hasStableIds() {
        return true;
    }
}
package com.example.android.navigationdrawerexample;
导入android.content.Context;
导入android.widget.ArrayAdapter;
导入java.util.HashMap;
导入java.util.List;
公共类StableArrayAdapter扩展了ArrayAdapter{
final int INVALID_ID=-1;
int mRowLayout;
列出mstring;
HashMap mIdMap=新的HashMap();
//建造师
公共StableArrayAdapter(上下文上下文、int行布局、列表对象){
超级(上下文、行布局、对象);
对于(int i=0;i=mIdMap.size()){
返回无效的_ID;
}
String item=getItem(位置);
返回mIdMap.get(项目);
}
@凌驾
公共布尔表ID(){
返回true;
}
}
更新2 我按照建议在此处将项目添加到对象,目前效果良好,但这与在设置适配器之前在MainActivity中添加项目不一样吗

public StableArrayAdapter(Context context, int rowLayout, List<String> objects) {
    super(context, rowLayout, objects);

    objects.add("item 1");
    objects.add("item 2");
    objects.add("item 3");
    objects.add("item 4");
    objects.add("item 5");

    for (int i = 0; i < objects.size(); ++i) {
        mIdMap.put(objects.get(i), i);
    }
}
publicstablearrayadapter(上下文上下文、int行布局、列表对象){
超级(上下文、行布局、对象);
对象。添加(“第1项”);
对象。添加(“第2项”);
对象。添加(“第3项”);
对象。添加(“第4项”);
对象。添加(“第5项”);
对于(int i=0;i
更新3 对象的大小仅在构造函数中已知 和 mIdMap.put(“第6项”,objects.size());在代码中没有任何作用

 // constructor
    public StableArrayAdapter(Context context, int rowLayout, List<String> objects) {
        super(context, rowLayout, objects);

        this.objects = objects;

        objects.add("item 1");
        objects.add("item 2");
        objects.add("item 3");
        objects.add("item 4");
        objects.add("item 5");

        for (int i = 0; i < objects.size(); ++i) {
            mIdMap.put(objects.get(i), i);
        }

        mIdMap.put("item 6", objects.size());    // has no effect

    }

    public void addItem(String item) {
        int index = objects.size();
        mIdMap.put(item, index);
    }
//构造函数
公共StableArrayAdapter(上下文上下文、int行布局、列表对象){
超级(上下文、行布局、对象);
this.objects=对象;
对象。添加(“第1项”);
对象。添加(“第2项”);
对象。添加(“第3项”);
对象。添加(“第4项”);
对象。添加(“第5项”);
对于(int i=0;i
我通常会在ArrayList中添加项目,或者在适配器代码中修改对象(在您的情况下是StableArrayAdapter),而不是像您那样在适配器之外。但只要ArrayAdapter之外的对象与StableArlayAdapter中的列表共享相同的地址,就可以了。我想不是

在您的情况下,确保类似于
arraylist.add(“项目1”)
的代码将字符串添加到
stablerayadapter
中的arraylist对象上。同样,我怀疑不是这样

要加快速度,请发布
StableArrayAdapter
的代码。如果必须下载代码,读者就不方便提供帮助

新建议代码:

StableARayAdapter中,添加一个公共方法,如:

// This method is opposite of getItemId().
public void addItem(String item) {
    // Add the string into the objects
    objects.add(item);

    // size of objects should be added by one after add() above
    int index = objects.size();
    mIdMap.put(item, index);
}
外部稳定适配器:

listView.setAdapter(adapter);
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

// added the item and called notifyDataSetChanged();
adapter.addItem("item 1");
adapter.addItem("item 2");

adapter.notifyDataSetChanged();
注意:不要在arraylist中添加项,而是调用StableArrayAdapter的方法object adapter

更新1:问题在于DynamicListView类中的方法
setCheeseList
()和
swaplements
()不适用于动态添加项。另外,StableARayAdapter中的
addItem
()也会更改。 我已经在我的项目中解决了这个问题,但这不容易解释。所以我会努力的

代码建议:

public class StableArrayAdapter extends ArrayAdapter<String> implements DynamicListView.SwappableListAdapter {
   ...
   @Override
   public void swap(int indexOne, int indexTwo) {
      // Swap mIdMap object related to indexOne and indexTwo
      String item = getItem(indexOne);

      notifyDataSetChanged();
}
第1部分,来自:

private void handleCellSwitch() {
...
   swapElements(mCheeseList, originalItem, getPositionForView(switchView));
   ((BaseAdapter) getAdapter()).notifyDataSetChanged();
...
致:

注:

  • 我没有调用本地方法
    swapElements
    ()在mCheeseList之间交换值,而是调用接口
    swapableListAdapter
    的方法
    swap
    (),该方法在
    stablerayadapter
    类中实现
  • 基本上,这个想法取决于在
    stablerayadapter
    中获得正确的数据
第二部分 接口的代码SwappableListAdapter

public interface SwappableListAdapter {
        /**
         * Swaps between 2 items in the adapter, one is the mobile item, another is the selected item.
         * Method notifyDataSetChanged is called in the swap() when finished.
         * @param index1 The selected row view, dragged and to be moved.
         * @param index2 The row which moved due to the dragged row item.
         */
    public void swap(int index1, int index2);
}
注:

  • 这是在DynamicClistView类中创建的接口,因为这是将进行实际调用的类
  • 这将修复编译器错误问题
第三部分 用于在stablerayadapter类中实现swap()方法的代码

至:

public class StableArrayAdapter extends ArrayAdapter<String> implements DynamicListView.SwappableListAdapter {
   ...
   @Override
   public void swap(int indexOne, int indexTwo) {
      // Swap mIdMap object related to indexOne and indexTwo
      String item = getItem(indexOne);

      notifyDataSetChanged();
}
公共类StableArayAdapter扩展ArrayAdapter实现DynamicListView.SwappableListAdapter{
...
@凌驾
公共无效掉期(int indexOne,int indexTwo){
//交换与indexOne和indexTwo相关的中间映射对象
String item=getItem(indexOne);
notifyDataSetChanged();
}
注:

  • swap
    ()需要工作。我的项目不使用HashMap进行交换,而且我不喜欢HashMap的当前实现(来自Google engineer)。我可能有时间修复它。也许你可以修复此方法。希望你现在已经有了想法
  • stablerayadapter
    类现在实现接口
    swapableListAdapter
    ,并有权覆盖swap()
  • 接口的思想是,适配器现在是存储数据的中心点!当前的实现将数据存储在适配器和DynamicListView中,而这不应该

我通常会在ArrayList中添加项目或修改t中的对象
public class StableArrayAdapter extends ArrayAdapter<String> implements DynamicListView.SwappableListAdapter {
   ...
   @Override
   public void swap(int indexOne, int indexTwo) {
      // Swap mIdMap object related to indexOne and indexTwo
      String item = getItem(indexOne);

      notifyDataSetChanged();
}
public void addItem(String item) {
    // Add the string into the objects
    objects.add(item);

    // size of objects should be added by one after add() above
    int index = objects.size();
    mIdMap.put(item, index);
}
listView.setCheeseList(al);
listView.setAdapter(adapter);
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

// called addItem method inside MainActivity
adapter.addItem("item 1");
adapter.addItem("item 2");
adapter.addItem("item 3");
adapter.addItem("item 4");

adapter.notifyDataSetChanged();
    private void handleCellSwitch() {
     ...   
       swapElements(mCheeseList, originalItem, getPositionForView(switchView));
       ((BaseAdapter) getAdapter()).notifyDataSetChanged();
     ...
    }
   private void handleCellSwitch() { 
    ...      
      final SwappableListAdapter adapter = (SwappableListAdapter) getAdapter();
      adapter.swap(mCheeseList,originalItem, getPositionForView(switchView)); // I still had to pass the arraylist   
    ...
    }
public interface SwappableListAdapter {    
    public void swap(int index1, int index2);
}
public class StableArrayAdapter extends ArrayAdapter<String> implements DynamicListView.SwappableListAdapter {

    @Override
    public void swap(ArrayList a,int index1, int index2) {

        Object temp = a.get(index1);
        a.set(index1, a.get(index2));
        a.set(index2, temp);

        notifyDataSetChanged();
    }
}