以下是我的自定义适配器视图的代码。当我在onLayout方法中放置一个断点时,它会被调用两次。同样在层次结构查看器中,我看到重复的视图。
package com.me.practice.widgets;
import java.util.LinkedList;
import java.util.Queue;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.GestureDetector.OnGestureListener;
import android.view.View.MeasureSpec;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Gallery;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.Scroller;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
public class ScrollableAdapterView extends AdapterView<ListAdapter> {
public ScrollableAdapterView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}
//TO detect gestures
private GestureDetector mGesture;
protected Scroller mScroller;
private OnItemSelectedListener mOnItemSelected;
private OnItemClickListener mOnItemClicked;
protected int mCurrentX;
protected int mNextX;
private int mMaxX = Integer.MAX_VALUE;
private int mLeftViewIndex = -1;
private int mRightViewIndex = 0;
protected ListAdapter mAdapter;
private Queue<View> mRemovedViewQueue = new LinkedList<View>();
private synchronized void initView(Context mContext) {
mScroller = new Scroller(getContext());
mGesture = new GestureDetector(getContext(), mOnGesture);
}
@Override
public ListAdapter getAdapter() {
return mAdapter;
}
@Override
public View getSelectedView() {
// TODO Auto-generated method stub
return null;
}
@Override
public void setAdapter(ListAdapter adapter) {
mAdapter = adapter;
}
@Override
public void setSelection(int position) {
// TODO Auto-generated method stub
}
@Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (mAdapter == null) {
return;
}
renderViews();
if (!mScroller.isFinished()) {
post(new Runnable() {
@Override
public void run() {
requestLayout();
}
});
}
}
private void renderViews() {
renderFixedColumn(3);
renderScrollableViews();
}
private void renderScrollableViews() {
}
//Renders fixed columns...
private void renderFixedColumn(int fixedColumnUptoIndex) {
//View fixedLayout= findViewById(R.id.fixedviewsLayout);
int index=0;
LinearLayout fixedViewsLayout = new LinearLayout(getContext());
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.MATCH_PARENT);
//fixedViewsLayout.setId(R.id.fixedviewsLayout);
while (index < fixedColumnUptoIndex) {
View child = mAdapter.getView(index, mRemovedViewQueue.poll(), this);
fixedViewsLayout.addView(child, index);
index++;
}
addViewInLayout(fixedViewsLayout, 0, params, true);
fixedViewsLayout.measure(MeasureSpec.makeMeasureSpec(getWidth(),
MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(
getHeight(), MeasureSpec.AT_MOST));
relayoutMeasuredItem(fixedViewsLayout);
}
private void relayoutMeasuredItem(View child) {
final int w = child.getMeasuredWidth();
final int h = child.getMeasuredHeight();
final int childLeft = getLeft();
final int childRight = childLeft + w;
final int childTop = child.getTop();
final int childBottom = childTop + h;
child.layout(childLeft, childTop, childRight, childBottom);
}
//
private OnGestureListener mOnGesture = new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onDown(MotionEvent e) {
return ScrollableAdapterView.this.onDown(e);
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
return ScrollableAdapterView.this.onFling(e1, e2, velocityX,
velocityY);
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
synchronized (ScrollableAdapterView.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(
ScrollableAdapterView.this,
child, mLeftViewIndex + 1 + i,
mAdapter.getItemId(mLeftViewIndex + 1 + i)
);
}
if (mOnItemSelected != null) {
mOnItemSelected.onItemSelected(
ScrollableAdapterView.this,
child,
mLeftViewIndex + 1 + i,
mAdapter.getItemId(mLeftViewIndex + 1 + i)
);
}
break;
}
}
return true;
}
};
protected boolean onDown(MotionEvent e) {
// TODO Auto-generated method stub
return false;
}
protected boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
// TODO Auto-generated method stub
return false;
}
}
这是我的活动的oncreate方法..
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listviewdemo);
listview.setAdapter(mAdapter);
}
返回视图的getView方法:
public View getView(int position, View convertView, ViewGroup parent) {
View retval = LayoutInflater.from(parent.getContext()).inflate(R.layout.viewitem, null);
TextView title = (TextView) retval.findViewById(R.id.title);
title.setText(dataObjects[position]);
return retval;
}
答案 0 :(得分:-1)
我没有深入探讨,只是简单地回答你的问题 -
这是因为在渲染时,布局经过两次传递,测量传递和布局传递。它是在第二遍中,即布局传递,父视图定位子视图。在布局部分 - http://developer.android.com/reference/android/view/View.html
中查看此内容