我正在进行一个演示,因为我使用了水平listView来显示一些图像和文本,我已成功完成但我的问题是在图像加载时它显示相同的图像两次(在两个列表项中)。我的最后一张图片一直显示在我在Android中的水平ListView的第4个listitem中,有人可以帮我解决这个问题吗?我的适配器如下所示;
public class RecentAdapter extends BaseAdapter {
public ArrayList<Post> popularAry;
Viewholder localViewholder = null;
private Context mContext;
String resnID, reson;
Intent i;
public RecentAdapter(Context paramContext, ArrayList<Post> recentAry) {
this.mContext = paramContext;
this.popularAry = recentAry;
}
public int getCount() {
return this.popularAry.size();
}
public Object getItem(int paramInt) {
return Integer.valueOf(paramInt);
}
public long getItemId(int paramInt) {
return paramInt;
}
public View getView(final int paramInt, View paramView,
ViewGroup paramViewGroup) {
LayoutInflater localLayoutInflater = (LayoutInflater) this.mContext
.getSystemService("layout_inflater");
if (paramView == null) {
paramView = localLayoutInflater.inflate(
R.layout.raw_recent, paramViewGroup, false);
localViewholder = new Viewholder();
localViewholder.tv_name = ((TextView) paramView
.findViewById(R.id.tv_name));
localViewholder.tv_hrt = ((TextView) paramView
.findViewById(R.id.tv_hrt));
localViewholder.tv_cmnt = ((TextView) paramView
.findViewById(R.id.tv_cmnt));
localViewholder.iv_pic = ((ImageView) paramView
.findViewById(R.id.imageViewGridPostImage));
localViewholder.rl_det = (RelativeLayout)paramView.
findViewById(R.id.rl_det);
localViewholder.iv_hrt = ((Button) paramView
.findViewById(R.id.iv_hrt));
localViewholder.iv_cmnt = ((ImageView) paramView
.findViewById(R.id.iv_cmnt));
// localViewholder.iv_hrt = ((ImageView) paramView
// .findViewById(R.id.imageViewGridPostImage));
paramView.setTag(localViewholder);
} else {
localViewholder = (Viewholder) paramView.getTag();
}
localViewholder.tv_name.setText(popularAry.get(paramInt).postTitle);
localViewholder.tv_hrt.setText((popularAry.get(paramInt).postLikesCount)+"");
localViewholder.tv_cmnt.setText((popularAry.get(paramInt).postCommentsCount) + "");
UrlImageViewHelper.setUrlDrawable(localViewholder.iv_pic, popularAry.get(paramInt).postImagePath, null, 3600000);
if(paramInt == 7){
localViewholder.iv_pic.setBackgroundResource(R.drawable.ic_morepost);
}
if (popularAry.get(paramInt).likedThisPost) {
localViewholder.iv_hrt.setBackgroundResource(R.drawable.btn_likes);
} else {
localViewholder.iv_hrt.setBackgroundResource(R.drawable.btn_liked);
// localViewholder.iv_hrt.setCompoundDrawablesWithIntrinsicBounds(
// R.drawable.btn_liked, 0, 0, 0);
}
return paramView;
}
static class Viewholder {
TextView tv_name;
ImageView iv_pic,iv_cmnt;
Button iv_hrt;
TextView tv_hrt,tv_cmnt;
RelativeLayout rl_det;
}
}
水平ListView
public class HorizontialListView extends AdapterView<ListAdapter> {
public boolean mAlwaysOverrideTouch = true;
protected ListAdapter mAdapter;
private int mLeftViewIndex = -1;
private int mRightViewIndex = 0;
protected int mCurrentX;
protected int mNextX;
private int mMaxX = Integer.MAX_VALUE;
private int mDisplayOffset = 0;
protected Scroller mScroller;
private GestureDetector mGesture;
private Queue<View> mRemovedViewQueue = new LinkedList<View>();
private OnItemSelectedListener mOnItemSelected;
private OnItemClickListener mOnItemClicked;
public HorizontialListView(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
private void initView() {
mLeftViewIndex = -1;
mRightViewIndex = 0;
mDisplayOffset = 0;
mCurrentX = 0;
mNextX = 0;
mMaxX = Integer.MAX_VALUE;
mScroller = new Scroller(getContext());
mGesture = new GestureDetector(getContext(), mOnGesture);
}
@Override
public void setOnItemSelectedListener(AdapterView.OnItemSelectedListener listener) {
mOnItemSelected = listener;
}
@Override
public void setOnItemClickListener(AdapterView.OnItemClickListener listener){
mOnItemClicked = listener;
}
private DataSetObserver mDataObserver = new DataSetObserver() {
@Override
public void onChanged() {
// TODO Auto-generated method stub
super.onChanged();
}
@Override
public void onInvalidated() {
// TODO Auto-generated method stub
super.onInvalidated();
}
};
@Override
public ListAdapter getAdapter() {
return mAdapter;
}
@Override
public View getSelectedView() {
//TODO: implement
return null;
}
@Override
public void setAdapter(ListAdapter adapter) {
if(mAdapter != null) {
mAdapter.unregisterDataSetObserver(mDataObserver);
}
mAdapter = adapter;
mAdapter.registerDataSetObserver(mDataObserver);
initView();
removeAllViewsInLayout();
requestLayout();
}
@Override
public void setSelection(int position) {
//TODO: implement
}
private void addAndMeasureChild(final View child, int viewPos) {
LayoutParams params = child.getLayoutParams();
if(params == null) {
params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
}
addViewInLayout(child, viewPos, params, true);
child.measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST),
MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.AT_MOST));
}
@Override
protected synchronized void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if(mAdapter == null){
return;
}
if(mScroller.computeScrollOffset()){
int scrollx = mScroller.getCurrX();
mNextX = scrollx;
}
if(mNextX < 0){
mNextX = 0;
mScroller.forceFinished(true);
}
if(mNextX > mMaxX) {
mNextX = mMaxX;
mScroller.forceFinished(true);
}
int dx = mCurrentX - mNextX;
removeNonVisibleItems(dx);
fillList(dx);
positionItems(dx);
mCurrentX = mNextX;
if(!mScroller.isFinished()){
post(new Runnable(){
@Override
public void run() {
requestLayout();
}
});
}
}
private void fillList(final int dx) {
int edge = 0;
View child = getChildAt(getChildCount()-1);
if(child != null) {
edge = child.getRight();
}
fillListRight(edge, dx);
edge = 0;
child = getChildAt(0);
if(child != null) {
edge = child.getLeft();
}
fillListLeft(edge, dx);
}
private void fillListRight(int rightEdge, final int dx) {
while(rightEdge + dx < getWidth() && mRightViewIndex < mAdapter.getCount()) {
View child = mAdapter.getView(mRightViewIndex, mRemovedViewQueue.poll(), this);
addAndMeasureChild(child, -1);
rightEdge += child.getMeasuredWidth();
if(mRightViewIndex == mAdapter.getCount()-1){
mMaxX = mCurrentX + rightEdge - getWidth();
}
mRightViewIndex++;
}
}
private void fillListLeft(int leftEdge, final int dx) {
while(leftEdge + dx > 0 && mLeftViewIndex >= 0) {
View child = mAdapter.getView(mLeftViewIndex, mRemovedViewQueue.poll(), this);
addAndMeasureChild(child, 0);
leftEdge -= child.getMeasuredWidth();
mLeftViewIndex--;
mDisplayOffset -= child.getMeasuredWidth();
}
}
private void removeNonVisibleItems(final int dx) {
View child = getChildAt(0);
while(child != null && child.getRight() + dx <= 0) {
mDisplayOffset += child.getMeasuredWidth();
mRemovedViewQueue.offer(child);
removeViewInLayout(child);
mLeftViewIndex++;
child = getChildAt(0);
}
child = getChildAt(getChildCount()-1);
while(child != null && child.getLeft() + dx >= getWidth()) {
mRemovedViewQueue.offer(child);
removeViewInLayout(child);
mRightViewIndex--;
child = getChildAt(getChildCount()-1);
}
}
private void positionItems(final int dx) {
if(getChildCount() > 0){
mDisplayOffset += dx;
int left = mDisplayOffset;
for(int i=0;i<getChildCount();i++){
View child = getChildAt(i);
int childWidth = child.getMeasuredWidth();
child.layout(left, 0, left + childWidth, child.getMeasuredHeight());
left += childWidth;
}
}
}
public synchronized void scrollTo(int x) {
mScroller.startScroll(mNextX, 0, x - mNextX, 0);
requestLayout();
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
boolean handled = mGesture.onTouchEvent(ev);
return handled;
}
protected boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
synchronized(HorizontialListView.this){
mScroller.fling(mNextX, 0, (int)-velocityX, 0, 0, mMaxX, 0, 0);
}
requestLayout();
return true;
}
protected boolean onDown(MotionEvent e) {
mScroller.forceFinished(true);
return true;
}
private OnGestureListener mOnGesture = new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onDown(MotionEvent e) {
return HorizontialListView.this.onDown(e);
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
return HorizontialListView.this.onFling(e1, e2, velocityX, velocityY);
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
synchronized(HorizontialListView.this){
mNextX += (int)distanceX;
}
requestLayout();
return true;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
Rect viewRect = new Rect();
for(int i=0;i<getChildCount();i++){
View child = getChildAt(i);
int left = child.getLeft();
int right = child.getRight();
int top = child.getTop();
int bottom = child.getBottom();
viewRect.set(left, top, right, bottom);
if(viewRect.contains((int)e.getX(), (int)e.getY())){
if(mOnItemClicked != null){
mOnItemClicked.onItemClick(HorizontialListView.this, child, mLeftViewIndex + 1 + i, 0);
}
if(mOnItemSelected != null){
mOnItemSelected.onItemSelected(HorizontialListView.this, child, mLeftViewIndex + 1 + i, 0);
}
break;
}
}
return true;
}
};
}
答案 0 :(得分:1)
使用RecycleView而不是ListView,它可以节省大量时间。如果你今年看到谷歌IO,安卓团队建议“忘记”痛苦的列表视图。在持有人绑定逻辑中看起来像问题。如果回收视图使用绑定更舒适,代码重构不会花费很多时间。
Android开发人员资源包含良好的example