无论何时更新GridView/ListView,都可以在适配器上调用notifyDatasetChanged,该适配器用新的数据重新填充列表,删除当前列表中的所有内容。
现在,以这个小视频为例,来自L Preview设计指南
在你看到的唯一改变是适配器重新加载时没有任何“闪烁”的新条目出现的情况下,是否有可能实现同样的效果?还是这是现在只能在L中完成的事情?
在添加新注释时,也可以在Google Keep应用程序中找到这种效果。
发布于 2014-08-21 19:54:25
恐怕这都是视觉上的诡计--也就是动画。
...removing当前在列表中的所有内容.
实际上,不是。
notifyDataSetChanged只告诉底层观察者数据已经改变了。就这样。作为响应,为每个可见视图调用getView(...) -- ListView#getChildCount()可访问的数字。由于索引已经更改(添加/删除项),或者保存在这些索引的对象中的数据已更改(^)(一个或多个项已更改),因此数据将通过随后对ListView#getView(...)的调用而可视化地刷新(^)。
“安卓开发者”有一段有趣的视频,解释了你如何产生你想要的效果:DevBytes: ListView细胞插入动画。
视频/示例只讨论单个项目的插入。但是它应该可以扩展到所有具有一定时间和数学技能的数据操作。
我能够扩展示例代码以插入多个项。我把动画改成了更简单的α淡入。单击Add row按钮会向列表视图中添加一个随机项目数(包括1到3)。如下所示:

Psuedo-工作流:
Rect中)和快照(在BitmapDrawables中)。OnPreDrawListener添加到ListView的ViewTreeObserver中。onPreDraw(...)时,将准备绘制新项。我们可以使用带有相应索引的ListView#getChildAt(...)访问它们的ListView#getChildAt(...)。getChildAt(..)访问的项目被分配到translation_y动画器中,以使它们脱离屏幕(或超出列表视图界限)。请注意,动画的类型(alpha、翻译、缩放或任何这些组合)相对来说是微不足道的。我想,如果是GridView或StaggeredGridView(保存),这将更加困难--这仅仅是因为数学将涉及X和Y的翻译。不过,工作流应该保持不变。
(^) -语法上不正确,但很自然。
发布于 2014-08-27 09:59:42
这可以通过获取视图并更改其中的数据来实现。我包含了一个示例,在长时间单击时,您可以更改数据,而不需要刷新可见项,也不需要调用notifyDataSetChanged()。
这个问题已经在Google I/O 2010上被问到,你可以在这里观看:
改编自沃盖拉的代码
package com.example.stableids;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.os.Build;
import android.os.Bundle;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.database.DataSetObserver;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
@SuppressLint("NewApi")
public class MainActivity extends Activity {
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ListView listview = (ListView) findViewById(R.id.listview);
String[] values = new String[] { "Android", "iPhone", "WindowsMobile",
"Blackberry", "WebOS", "Ubuntu", "Windows7", "Max OS X",
"Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X", "Linux",
"OS/2", "Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2",
"Android", "iPhone", "WindowsMobile" };
final ArrayList<String> list = new ArrayList<String>();
for (int i = 0; i < values.length; ++i) {
list.add(values[i]);
}
final StableArrayAdapter adapter = new StableArrayAdapter(this,
android.R.layout.simple_list_item_1, list);
listview.setAdapter(adapter);
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@SuppressLint("NewApi")
@Override
public void onItemClick(AdapterView<?> parent, final View view,
final int position, long id) {
final String item = (String) parent.getItemAtPosition(position);
view.animate().setDuration(2000).alpha(0)
.withEndAction(new Runnable() {
@Override
public void run() {
int i = list.indexOf(item);
list.remove(item);
list.add(i, "MODIFIED");
adapter.mIdMap.put("MODIFIED", position);
TextView tv = (TextView)view.findViewById(android.R.id.text1);
tv.setText("MODIFIED");
//adapter.notifyDataSetChanged();
view.setAlpha(1);
}
});
}
});
}
private class StableArrayAdapter extends ArrayAdapter<String> {
HashMap<String, Integer> mIdMap = new HashMap<String, Integer>();
public StableArrayAdapter(Context context, int textViewResourceId,
List<String> objects) {
super(context, textViewResourceId, objects);
for (int i = 0; i < objects.size(); ++i) {
mIdMap.put(objects.get(i), i);
}
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Log.d("STABLE ID", "getView called for " + position + " position");
return super.getView(position, convertView, parent);
}
@Override
public long getItemId(int position) {
String item = getItem(position);
return mIdMap.get(item);
}
@Override
public boolean hasStableIds() {
return true;
}
}
}发布于 2014-08-21 13:15:57
更新GridView/ListView而不重新填充
如果每次更新和删除时都使用相同的数组列表而不创建新的ArrayList,那么adapter.notifyDatasetChanged()方法就可以工作。请每次都使用相同的arrayList,不要创建适配器类的新实例
https://stackoverflow.com/questions/25373971
复制相似问题