Android 屏幕滚动时,GridView 中的项目会重复
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11245620/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Items inside GridView getting repeated when screen scrolls
提问by Lucas Jota
I'm using a GridView to show a set of Categories that user can chose. Each item of the grid is consisted by an ImageView and a TextView, both retrieved from server. When an item is touched, another activity is started.
我正在使用 GridView 来显示一组用户可以选择的类别。网格的每一项都由一个 ImageView 和一个 TextView 组成,两者都从服务器检索。当一个项目被触摸时,另一个活动开始。
I thought everything was going right, until I've noticed that some itens were getting repeated when I scrolls the screen. Whenever I scroll down trough the grid, and then back, itens change it? position and get duplicated. But even when I touch the messed up itens, the right values are send to the next activity.
我以为一切正常,直到我注意到当我滚动屏幕时有些项目会重复。每当我向下滚动网格然后返回时,它会改变它吗?位置并被复制。但即使当我触摸混乱的项目时,正确的值也会发送到下一个活动。
Looking in LogCat, any repeated request to server occurs. In fact, I've got this while scrolling:
查看 LogCat,任何对服务器的重复请求都会发生。事实上,我在滚动时得到了这个:
06-28 12:36:38.554: D/dalvikvm(358): GC_EXTERNAL_ALLOC freed 2061 objects / 156024 bytes in 51ms
06-28 12:36:42.915: D/dalvikvm(358): GC_FOR_MALLOC freed 6590 objects / 737528 bytes in 57ms
06-28 12:38:26.725: D/dalvikvm(358): GC_EXTERNAL_ALLOC freed 5426 objects / 468176 bytes in 71ms
06-28 12:38:26.875: D/dalvikvm(358): GC_EXTERNAL_ALLOC freed 409 objects / 17480 bytes in 68ms
Looks like everytime I scroll, itens get redraw...
看起来每次我滚动时,都会重新绘制...
UPDATE: It only redraw itens on the first time I scroll down the GridView. After this, all itens, including repeated ones, keeps on its places.
更新:它只在我第一次向下滚动 GridView 时重绘 itens。在此之后,所有 itens,包括重复的 itens,都会保持原位。
My java class:
我的java类:
public void proccess(){
int qtdCategorias = json.length();
imagens = new Drawable[qtdCategorias];
categorias = new String[qtdCategorias];
for (int i=0; i<qtdCategorias; i++){
JSONArray c = json.optJSONArray(i);
String urlAmigavel = null;
String imagemSite = null;
String nomeCategoria = null;
try {
urlAmigavel = c.getString(6);
imagemSite = c.getString(3);
nomeCategoria = c.getString(2);
} catch (JSONException e) {
Log.e("CategoriasJogarActivity", e.toString());
e.printStackTrace();
}
categorias[i] = nomeCategoria;
imagens[i] = getImagem(urlAmigavel, imagemSite);
}
gridview = (GridView) findViewById(R.id.include3);
ImageAdapter imageAdapter = new ImageAdapter(ctx, imagens, categorias);
gridview.setAdapter(imageAdapter);
gridview.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
String name = null;
String idt = null;
try {
JSONArray c = json.optJSONArray(position);
name = c.getString(2);
idt = c.getString(0);
} catch (JSONException e) {
Log.e("CategoriasJogarActivity",
"JSONException" + e.toString());
}
Intent in = new Intent(getApplicationContext(),
JogarActivity.class);
in.putExtra(TAG_NAME, name);
in.putExtra(TAG_ID, idt);
in.putExtra(TAG_PRIMEIRAPERGUNTA, true);
startActivity(in);
}
});
}
public Drawable getImagem(String urlAmigavel, String img) {
String url = "http://www.qranio.com/pergunta/" + urlAmigavel + "/"+ img;
InputStream is = null;
try {
URL urlImagem = new URL(url);
is = (InputStream) getObjeto(urlImagem);
} catch (MalformedURLException e1) {
Log.e("CategoriasJogarActivity", e1.toString());
e1.printStackTrace();
}
Drawable d = Drawable.createFromStream(is, "src");
return d;
}
private Object getObjeto(URL url) {
Object content = null;
try {
content = url.getContent();
} catch (IOException e) {
Log.e("CategoriasJogarActivity", e.toString());
e.printStackTrace();
}
return content;
}
imageAdapter class
图像适配器类
public class ImageAdapter extends BaseAdapter{
private Context mContext;
private final Drawable[] mThumbIds;
private final String[] mTextIds;
public ImageAdapter(Context c, Drawable[] d, String[] s) {
mContext = c;
mThumbIds = d;
mTextIds = s;
}
public int getCount() {
return mThumbIds.length;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
//create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
//ImageView imageView;
View v;
if (convertView == null) { // if it's not recycled, initialize some attributes
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
v = inflater.inflate(R.layout.gridview_item_layout, null);
TextView text = (TextView)v.findViewById(R.id.grid_item_text);
text.setText(mTextIds[position]);
ImageView image = (ImageView)v.findViewById(R.id.grid_item_image);
image.setImageDrawable(mThumbIds[position]);
} else {
v = (View) convertView;
}
return v;
}
}
gridview_item_layout xml
gridview_item_layout xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/gridview_item_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal" >
<ImageView android:id="@+id/grid_item_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:minHeight="100dip"
android:minWidth="100dip"
>
</ImageView>
<TextView android:id="@+id/grid_item_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="TextView"
android:gravity="center"
android:textColor="#F9A512"
android:textStyle="bold"
android:textSize="18dp"
>
</TextView>
</LinearLayout>
gridview xml
网格视图 xml
<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/gridview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:numColumns="auto_fit"
android:verticalSpacing="10dip"
android:horizontalSpacing="10dip"
android:stretchMode="columnWidth"
android:gravity="center"
android:background="#FFFFFF"
android:padding="5dip"
/>
I saw other questions about this same issue, but none of them answered. Any ideas of what's happening?
我看到了关于同一问题的其他问题,但没有人回答。对正在发生的事情有什么想法吗?
回答by Luksprog
It's normal that you see the same items as you scroll down the GridView
because in the getView
method you set the drawables for the ImageView
only when the convertView
is null
(for example for the first elements that are seen when the GridView
appear on the screen). If the convertView
is not null
, meaning you have a recycled row view, you don't set the correct image and you remain with the image that was previously set on this recycled view. Try to modify the getView
method like this:
这是正常的,你看到相同的项目,你向下滚动GridView
,因为在getView
方法设置为可绘制的ImageView
,只有当convertView
是null
(例如,用于当所看到的第一个元素GridView
出现在屏幕上)。如果convertView
不是null
,则意味着您有一个回收的行视图,您没有设置正确的图像,您将保留之前在此回收视图上设置的图像。尝试getView
像这样修改方法:
public View getView(int position, View convertView, ViewGroup parent) {
View v;
if (convertView == null) { // if it's not recycled, initialize some attributes
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
v = inflater.inflate(R.layout.gridview_item_layout, parent, false);
} else {
v = (View) convertView;
}
TextView text = (TextView)v.findViewById(R.id.grid_item_text);
text.setText(mTextIds[position]);
ImageView image = (ImageView)v.findViewById(R.id.grid_item_image);
image.setImageDrawable(mThumbIds[position]);
return v;
}
Clicking an element shows you the correct items because you use the position
parameter to retrieve the data.
单击一个元素会显示正确的项目,因为您使用position
参数来检索数据。
回答by ieselisra
These is my code for GirdView with Button + Textview
这些是我的带有 Button + Textview 的 GirdView 代码
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = mInflater.inflate(R.layout.grid_item, null);
} else {
holder = (ViewHolder) convertView.getTag();
}
TextView text = (TextView)convertView.findViewById(R.id.texto_grid);
text.setText(app_listaActiva_NOMBRES[position]);
Button image = (Button)convertView.findViewById(R.id.miniatura_grid);
image.setBackgroundResource(R.drawable.custom_button);
image.setOnClickListener(new MyOnClickListener2(position,app_listaActiva_SONIDOS));
return convertView;
}
回答by Krste Moskov
Send and gridview or listview and In constructor implement this method implement onscroll listener
Send 和 gridview 或 listview 并在构造函数中实现此方法实现 onscroll 侦听器
this.mGridView = mGridView;
this.mGridView.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
Log.v("onScrollStateChanged", "onScrollStateChanged");
if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
isScrollStop = true;
notifyDataSetChanged();
} else {
isScrollStop = false;
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
Log.v("onScroll", "onScroll");
}
});
回答by Nikolay Podolnyy
Using ViewHolder
static class fixed repeating items for me.
ViewHolder
为我使用静态类固定重复项。
Also changing layout_width
and layout_height
to fill_parent
didn't help.
也在改变layout_width
和layout_height
对fill_parent
没有帮助。
I went through this tutorial http://android-vogue.blogspot.com/2011/06/custom-gridview-in-android-with.html
我浏览了本教程 http://android-vogue.blogspot.com/2011/06/custom-gridview-in-android-with.html
回答by osayilgan
Change here and try it again,
改这里再试试
View v;
if (convertView == null) { // if it's not recycled, initialize some attributes
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
v = inflater.inflate(R.layout.gridview_item_layout, null);
TextView text = (TextView)v.findViewById(R.id.grid_item_text);
text.setText(mTextIds[position]);
} else {
v = (View) convertView;
}
if(view!=null)
{
ImageView image = (ImageView)v.findViewById(R.id.grid_item_image);
image.setImageDrawable(mThumbIds[position]);
notifyDataSetChanged(); //Calling this helped to solve the problem.
}
return v;
}