Android DynamicListView项目在拖动时消失(&;滴
我遵循这个google教程,实现了一个用于拖放的动态ListView 它会显示listview中的所有项目,但当我拖放元素时,它们会消失 如果我在设置适配器之前添加元素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
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();
}
}