gpt4 book ai didi

android - ListView 中的 OutOfBoundsException

转载 作者:行者123 更新时间:2023-11-29 21:46:56 25 4
gpt4 key购买 nike

我正在使用 ListView 来呈现类似 GridView 的 Activity 。存在 OutOfBoundsException。这是日志。

03-21 11:47:13.106: E/AndroidRuntime(597): FATAL EXCEPTION: main
03-21 11:47:13.106: E/AndroidRuntime(597): java.lang.IndexOutOfBoundsException: Invalid index 1, size is 1
03-21 11:47:13.106: E/AndroidRuntime(597): at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
03-21 11:47:13.106: E/AndroidRuntime(597): at java.util.ArrayList.get(ArrayList.java:304)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.widget.HeaderViewListAdapter.getView(HeaderViewListAdapter.java:225)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.widget.AbsListView.obtainView(AbsListView.java:2022)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.widget.ListView.measureHeightOfChildren(ListView.java:1244)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.widget.ListView.onMeasure(ListView.java:1155)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.view.View.measure(View.java:12752)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4698)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.widget.FrameLayout.onMeasure(FrameLayout.java:293)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.view.View.measure(View.java:12752)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4698)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1369)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.widget.LinearLayout.measureVertical(LinearLayout.java:660)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.widget.LinearLayout.onMeasure(LinearLayout.java:553)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.view.View.measure(View.java:12752)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.widget.RelativeLayout.measureChild(RelativeLayout.java:579)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:392)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.view.View.measure(View.java:12752)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4698)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.widget.FrameLayout.onMeasure(FrameLayout.java:293)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.view.View.measure(View.java:12752)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4698)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1369)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.widget.LinearLayout.measureVertical(LinearLayout.java:660)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.widget.LinearLayout.onMeasure(LinearLayout.java:553)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.view.View.measure(View.java:12752)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4698)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.widget.FrameLayout.onMeasure(FrameLayout.java:293)
03-21 11:47:13.106: E/AndroidRuntime(597): at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2265)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.view.View.measure(View.java:12752)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1074)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2462)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.os.Handler.dispatchMessage(Handler.java:99)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.os.Looper.loop(Looper.java:137)
03-21 11:47:13.106: E/AndroidRuntime(597): at android.app.ActivityThread.main(ActivityThread.java:4486)
03-21 11:47:13.106: E/AndroidRuntime(597): at java.lang.reflect.Method.invokeNative(Native Method)
03-21 11:47:13.106: E/AndroidRuntime(597): at java.lang.reflect.Method.invoke(Method.java:511)
03-21 11:47:13.106: E/AndroidRuntime(597): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
03-21 11:47:13.106: E/AndroidRuntime(597): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
03-21 11:47:13.106: E/AndroidRuntime(597): at dalvik.system.NativeStart.main(Native Method)

我的 ListToGridAdapter 如下:

public class ListToGridAdapter extends BaseAdapter implements OnClickListener, OnLongClickListener {

/**
* The wrapper content --> adapter
*/
private SimpleAdapter mAdapter = null;
/**
* The number columns
*/
private int mColumns = 1;
/**
* The real onItemClickListener
*/
private OnGridItemClickListener mGridListener;
/**
* The real onItemLongClickListener
*/
private OnGridItemLongClickListener mGridLongClickListener;

/**
* The Context Object
*/
private Context mContext;

private int sidebarPixals = 0;
private int sideBlankPixals = 0;

@Override
public View getView(int position, View convertView, ViewGroup parent) {

if (mColumns == 1) {
View child = mAdapter.getView(position, convertView, parent);
setOnItemClickListenerIfNeed(child, position, position);
setOnItemLongClickListenerIfNeed(child, position, position);
// no need
return child;
}

return bindGridView(position, convertView, parent);
}

protected View bindGridView(int position, View convertView, ViewGroup parent) {
ViewGroup root = null;
if (convertView == null || !(convertView instanceof ViewGroup)) {
root = createRoot();
root.setClickable(false);
root.setFocusable(false);
} else {
root = (ViewGroup) convertView;
}
// columns = 3
// pos --> real pos
// 0 --> 0 1 2
// 1 --> 3 4 5
// 2 --> 6 7 8
// so do this
return bindView(root, position);
}

protected ViewGroup bindView(ViewGroup root, int pos) {

final int count = mAdapter.getCount();
final int childCount = root.getChildCount();

for (int i = 0; i < mColumns; i++) {
// real position
int index = mColumns * pos + i;

// 不足一行时,直接返回现有状态
if (index == count) {
// fix bug : root是有可能是系统缓存的root,这里直接返回root将导致如果此行数量
// 不够columns,就会使用缓存的root里的child,为了避免这个问题,必须
// 将缓存的child移除。
removeCacheChild(root, index);
break;
} else if (index > count) {
throw new UnknownError("unknowError");
}

View child = mAdapter.getView(index, root.getChildAt(i), root);

setOnItemLongClickListenerIfNeed(child, pos, index);
setOnItemClickListenerIfNeed(child, pos, index);

if (childCount == mColumns) {
// root已经包含了Item,就没有必要继续添加了。
continue;
} else {
if (i == 0 && childCount != 0) {
// 如果root已经包含item,但是并不全,这里就移除重新添加
// FIXME 也许还有更好的方案
root.removeAllViews();
}
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
// LinearLayout.LayoutParams.WRAP_CONTENT,
(mContext.getResources().getDisplayMetrics().widthPixels - sidebarPixals - sideBlankPixals)
/ mColumns,
LinearLayout.LayoutParams.WRAP_CONTENT);
child.setFocusable(true);
child.setClickable(true);
if (child instanceof ViewGroup) {
((ViewGroup) child)
.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
}
root.addView(child, lp);
}
}
return root;
}

/**
* remove child view in cache of root
*/
private void removeCacheChild(ViewGroup root, int index) {
int realColumns = (index - 1) % mColumns;
int moveCount = (mColumns - 1) - realColumns;

for (int i = 0; i < moveCount; i++) {
final View child = root.getChildAt((mColumns - 1 - i));
if (child != null) {
root.removeView(child);
}
}
}

/**
* create root for item of ListView
*/
protected ViewGroup createRoot() {
LinearLayout root = new LinearLayout(mContext);
root.setOrientation(LinearLayout.HORIZONTAL);
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
root.setLayoutParams(lp);
return root;
}

private boolean setOnItemClickListenerIfNeed(View child, int pos,
int realPos) {
if (mGridListener == null) {
return false;
}
child.setOnClickListener(this);
child.setTag(R.id.pos, pos);
child.setTag(R.id.realPos, realPos);
return true;
}

private boolean setOnItemLongClickListenerIfNeed(View child, int pos,
int realPos) {
if (mGridLongClickListener == null) {
return false;
}
child.setOnLongClickListener(this);
child.setTag(R.id.pos, pos);
child.setTag(R.id.realPos, realPos);
return true;
}

public void setOnItemClickListener(OnGridItemClickListener listener) {
this.mGridListener = listener;
}

public void setOnItemLongClickListener(OnGridItemLongClickListener listener){
this.mGridLongClickListener = listener;
}

public void setNumColumns(int columns) {
this.mColumns = columns;
}

public int getNumColumns() {
return mColumns;
}

public ListToGridAdapter(Context context, SimpleAdapter adapter) {
this.mContext = context;
this.mAdapter = adapter;
int model = YoutubeAPI.getKindleFireModel();

if (model == 1){
sideBlankPixals = 10 * 2;
sidebarPixals = 0;
} else if (model == 2){
sideBlankPixals = 10 * 2;
sidebarPixals = 60;
} else if (model == 3){
sideBlankPixals = (int)(10 * 2 * 1.5);
sidebarPixals = 78;
} else if (model == 4){
sideBlankPixals = (int)(10 * 2 * 1.5);
sidebarPixals = 90;
}

}

@Override
public int getCount() {
int count = (int) Math.ceil(mAdapter.getCount() / (double) mColumns);
return count;
}

@Override
public Object getItem(int position) {
return mAdapter.getItem(position);
}

@Override
public long getItemId(int position) {
return mAdapter.getItemId(position);
}

@Override
public boolean hasStableIds() {
return mAdapter.hasStableIds();
}

@Override
public void registerDataSetObserver(DataSetObserver observer) {
mAdapter.registerDataSetObserver(observer);
}

@Override
public void unregisterDataSetObserver(DataSetObserver observer) {
mAdapter.unregisterDataSetObserver(observer);
}

@Override
public boolean areAllItemsEnabled() {
return mAdapter.areAllItemsEnabled();
}

@Override
public boolean isEnabled(int position) {
return mAdapter.isEnabled(position);
}

@Override
public int getItemViewType(int position) {
return mAdapter.getItemViewType(position);
}

@Override
public int getViewTypeCount() {
return mAdapter.getViewTypeCount();
}

@Override
public boolean isEmpty() {
return mAdapter.isEmpty();
}

public ListAdapter getWrappedAdapter() {
return mAdapter;
}

public static interface OnGridItemClickListener {
public void onItemClick(int pos, int realPos);
}

public static interface OnGridItemLongClickListener{
public void onItemLongClick(int pos, int realPos);
}

@Override
public void onClick(View v) {
if (mGridListener == null) {
// no need to feedback
}
int pos = (Integer) v.getTag(R.id.pos);
int realPos = (Integer) v.getTag(R.id.realPos);

mGridListener.onItemClick(pos, realPos);
}

@Override
public boolean onLongClick(View v) {
if (mGridLongClickListener == null) {
// no need to feedback
}
int pos = (Integer) v.getTag(R.id.pos);
int realPos = (Integer) v.getTag(R.id.realPos);

mGridLongClickListener.onItemLongClick(pos, realPos);
return true;
}

}

在 Activity 中,

ListToGridAdapter mAdapter = new ListToGridAdapter(this, mVideoGridviewAdapter);
mAdapter.setNumColumns(3);

pullToRefreshListview.setAdapter(mAdapter);

mVideoGridviewAdapter 是一个简单的适配器。

问题出在哪里?好像是 ListView 的页脚,但我不知道如何修复它。

==== 编辑 =====

在 Activity 中,我添加了一些 AsyncTask 来刷新 ListView 。在 onPostExecute 中,我将一些项目添加到 ListView 中,使 ListView 更长,并将 ListView 的页脚 View 从 View.VISIBLE 更改为 View.INVISIBLE,这重要吗?

最佳答案

我自己想出来的。

当更改包含 ListView 的 fragment 时, ListView 会先清空自己,然后 ListView 在滚动时会记住索引,然后,当重新加载 ListView 时,会发生IndexOutOfBoundsException

所以解决方案是:销毁时重置 ListView 的适配器,代码 fragment 如下

public void onDestroyView() {
if (listview != null && mVideoGridviewAdapter != null) {
ListToGridWrapper<GridviewAdapter> mAdapter = new ListToGridWrapper<GridviewAdapter>(getActivity(), mVideoGridviewAdapter);
mAdapter.setNumColumns(2);
listview.setAdapter(mAdapter);
}
super.onDestroyView();
}

关于android - ListView 中的 OutOfBoundsException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15539188/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com