下面列出了android.view.View#isDrawingCacheEnabled ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@SuppressWarnings("unchecked")
private void enterContactDetail(Context context, ContactViewHolder holder, Contact contact) {
if (mItemTouchHelper.isOpened()) {
mItemTouchHelper.closeOpened();
return;
}
Activity activity = (Activity) context;
View content = activity.getWindow().getDecorView().findViewById(android.R.id.content);
if (content.isDrawingCacheEnabled()) {
content.setDrawingCacheEnabled(false);
}
content.setDrawingCacheEnabled(true);
content.buildDrawingCache();
Bitmap bitmap = content.getDrawingCache();
ContactDetailActivity.start(activity, bitmap, contact,
Pair.create(holder.getView(R.id.tx_name), activity.getString(R.string.transition_name)),
Pair.create(holder.getView(R.id.ic_head), activity.getString(R.string.transition_head)),
Pair.create(holder.getView(R.id.ic_location), activity.getString(R.string.transition_location_icon)),
Pair.create(holder.getView(R.id.tx_location), activity.getString(R.string.transition_location)));
}
public static Bitmap getScreenshot()
{
Activity activity = ReportingActivity.getForegroundInstance();
if(activity == null){
return null;
}
Window window = activity.getWindow();
if(window == null){
return null;
}
View view = window.getDecorView();
if(view == null){
return null;
}
view.buildDrawingCache();
Bitmap cache = view.getDrawingCache();
Bitmap screenshot = cache.copy(cache.getConfig(), false);
cache = null;
if(!view.isDrawingCacheEnabled()){
view.destroyDrawingCache();
}
return screenshot;
}
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
boolean result;
final int save = canvas.save(Canvas.CLIP_SAVE_FLAG);
if (Build.VERSION.SDK_INT >= 11) {
result = super.drawChild(canvas, child, drawingTime);
} else {
if (child.isDrawingCacheEnabled()) {
child.setDrawingCacheEnabled(false);
}
result = super.drawChild(canvas, child, drawingTime);
}
canvas.restoreToCount(save);
return result;
}
/**
* Return the bitmap of screen.
*
* @param activity The activity.
* @param isDeleteStatusBar True to delete status bar, false otherwise.
* @return the bitmap of screen
*/
public static Bitmap screenShot(@NonNull final Activity activity, boolean isDeleteStatusBar) {
View decorView = activity.getWindow().getDecorView();
boolean drawingCacheEnabled = decorView.isDrawingCacheEnabled();
boolean willNotCacheDrawing = decorView.willNotCacheDrawing();
decorView.setDrawingCacheEnabled(true);
decorView.setWillNotCacheDrawing(false);
Bitmap bmp = decorView.getDrawingCache();
if (bmp == null) {
decorView.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
decorView.layout(0, 0, decorView.getMeasuredWidth(), decorView.getMeasuredHeight());
decorView.buildDrawingCache();
bmp = Bitmap.createBitmap(decorView.getDrawingCache());
}
if (bmp == null) {
return null;
}
DisplayMetrics dm = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
Bitmap ret;
if (isDeleteStatusBar) {
Resources resources = activity.getResources();
int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
int statusBarHeight = resources.getDimensionPixelSize(resourceId);
ret = Bitmap.createBitmap(bmp,
0,
statusBarHeight,
dm.widthPixels,
dm.heightPixels - statusBarHeight);
} else {
ret = Bitmap.createBitmap(bmp, 0, 0, dm.widthPixels, dm.heightPixels);
}
decorView.destroyDrawingCache();
decorView.setWillNotCacheDrawing(willNotCacheDrawing);
decorView.setDrawingCacheEnabled(drawingCacheEnabled);
return ret;
}
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
boolean result;
LayoutParams lp = (LayoutParams) child.getLayoutParams();
int save = canvas.save(2);
if (!(!this.mCanSlide || lp.slideable || this.mSlideableView == null)) {
canvas.getClipBounds(this.mTmpRect);
if (isLayoutRtlSupport()) {
this.mTmpRect.left = Math.max(this.mTmpRect.left, this.mSlideableView.getRight());
} else {
this.mTmpRect.right = Math.min(this.mTmpRect.right, this.mSlideableView.getLeft());
}
canvas.clipRect(this.mTmpRect);
}
if (VERSION.SDK_INT >= 11) {
result = super.drawChild(canvas, child, drawingTime);
} else if (!lp.dimWhenOffset || this.mSlideOffset <= 0.0f) {
if (child.isDrawingCacheEnabled()) {
child.setDrawingCacheEnabled(false);
}
result = super.drawChild(canvas, child, drawingTime);
} else {
if (!child.isDrawingCacheEnabled()) {
child.setDrawingCacheEnabled(true);
}
Bitmap cache = child.getDrawingCache();
if (cache != null) {
canvas.drawBitmap(cache, (float) child.getLeft(), (float) child.getTop(), lp.dimPaint);
result = false;
} else {
Log.e(TAG, "drawChild: child view " + child + " returned null drawing cache");
result = super.drawChild(canvas, child, drawingTime);
}
}
canvas.restoreToCount(save);
return result;
}
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
boolean result;
final int save = canvas.save(Canvas.CLIP_SAVE_FLAG);
if (mCanSlide && !lp.slideable && mSlideableView != null) {
// Clip against the slider; no sense drawing what will immediately be covered.
canvas.getClipBounds(mTmpRect);
mTmpRect.right = Math.min(mTmpRect.right, mSlideableView.getLeft());
canvas.clipRect(mTmpRect);
}
if (Build.VERSION.SDK_INT >= 11) { // HC
result = super.drawChild(canvas, child, drawingTime);
} else {
if (lp.dimWhenOffset && mSlideOffset > 0) {
if (!child.isDrawingCacheEnabled()) {
child.setDrawingCacheEnabled(true);
}
final Bitmap cache = child.getDrawingCache();
if (cache != null) {
canvas.drawBitmap(cache, child.getLeft(), child.getTop(), lp.dimPaint);
result = false;
} else {
Log.e(TAG, "drawChild: child view " + child + " returned null drawing cache");
result = super.drawChild(canvas, child, drawingTime);
}
} else {
if (child.isDrawingCacheEnabled()) {
child.setDrawingCacheEnabled(false);
}
result = super.drawChild(canvas, child, drawingTime);
}
}
canvas.restoreToCount(save);
return result;
}
/**
* View to bitmap.
*
* @param view The view.
* @return bitmap
*/
public static Bitmap view2Bitmap(final View view) {
if (view == null) return null;
boolean drawingCacheEnabled = view.isDrawingCacheEnabled();
boolean willNotCacheDrawing = view.willNotCacheDrawing();
view.setDrawingCacheEnabled(true);
view.setWillNotCacheDrawing(false);
Bitmap drawingCache = view.getDrawingCache();
Bitmap bitmap;
if (null == drawingCache) {
view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
view.buildDrawingCache();
drawingCache = view.getDrawingCache();
if (drawingCache != null) {
bitmap = Bitmap.createBitmap(drawingCache);
} else {
bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
}
} else {
bitmap = Bitmap.createBitmap(drawingCache);
}
view.destroyDrawingCache();
view.setWillNotCacheDrawing(willNotCacheDrawing);
view.setDrawingCacheEnabled(drawingCacheEnabled);
return bitmap;
}
/**
* Return the bitmap of screen.
*
* @param activity The activity.
* @param isDeleteStatusBar True to delete status bar, false otherwise.
* @return the bitmap of screen
*/
public static Bitmap screenShot(@NonNull final Activity activity, boolean isDeleteStatusBar) {
View decorView = activity.getWindow().getDecorView();
boolean drawingCacheEnabled = decorView.isDrawingCacheEnabled();
boolean willNotCacheDrawing = decorView.willNotCacheDrawing();
decorView.setDrawingCacheEnabled(true);
decorView.setWillNotCacheDrawing(false);
Bitmap bmp = decorView.getDrawingCache();
if (bmp == null) {
decorView.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
decorView.layout(0, 0, decorView.getMeasuredWidth(), decorView.getMeasuredHeight());
decorView.buildDrawingCache();
bmp = Bitmap.createBitmap(decorView.getDrawingCache());
}
if (bmp == null) return null;
DisplayMetrics dm = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
Bitmap ret;
if (isDeleteStatusBar) {
Resources resources = activity.getResources();
int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
int statusBarHeight = resources.getDimensionPixelSize(resourceId);
ret = Bitmap.createBitmap(
bmp,
0,
statusBarHeight,
dm.widthPixels,
dm.heightPixels - statusBarHeight
);
} else {
ret = Bitmap.createBitmap(bmp, 0, 0, dm.widthPixels, dm.heightPixels);
}
decorView.destroyDrawingCache();
decorView.setWillNotCacheDrawing(willNotCacheDrawing);
decorView.setDrawingCacheEnabled(drawingCacheEnabled);
return ret;
}
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
boolean result;
final int save = canvas.save(Canvas.CLIP_SAVE_FLAG);
if (mCanSlide && !lp.slideable && mSlideableView != null) {
// Clip against the slider; no sense drawing what will immediately be covered.
canvas.getClipBounds(mTmpRect);
mTmpRect.right = Math.min(mTmpRect.right, mSlideableView.getLeft());
canvas.clipRect(mTmpRect);
}
if (Build.VERSION.SDK_INT >= 11) { // HC
result = super.drawChild(canvas, child, drawingTime);
} else {
if (lp.dimWhenOffset && mSlideOffset > 0) {
if (!child.isDrawingCacheEnabled()) {
child.setDrawingCacheEnabled(true);
}
final Bitmap cache = child.getDrawingCache();
if (cache != null) {
canvas.drawBitmap(cache, child.getLeft(), child.getTop(), lp.dimPaint);
result = false;
} else {
Log.e(TAG, "drawChild: child view " + child + " returned null drawing cache");
result = super.drawChild(canvas, child, drawingTime);
}
} else {
if (child.isDrawingCacheEnabled()) {
child.setDrawingCacheEnabled(false);
}
result = super.drawChild(canvas, child, drawingTime);
}
}
canvas.restoreToCount(save);
return result;
}
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
boolean result;
final int save = canvas.save(Canvas.CLIP_SAVE_FLAG);
if (mCanSlide && !lp.slideable && mSlideableView != null) {
// Clip against the slider; no sense drawing what will immediately be covered.
canvas.getClipBounds(mTmpRect);
mTmpRect.right = Math.min(mTmpRect.right, mSlideableView.getLeft());
canvas.clipRect(mTmpRect);
}
if (Build.VERSION.SDK_INT >= 11) { // HC
result = super.drawChild(canvas, child, drawingTime);
} else {
if (lp.dimWhenOffset && mSlideOffset > 0) {
if (!child.isDrawingCacheEnabled()) {
child.setDrawingCacheEnabled(true);
}
final Bitmap cache = child.getDrawingCache();
if (cache != null) {
canvas.drawBitmap(cache, child.getLeft(), child.getTop(), lp.dimPaint);
result = false;
} else {
Log.e(TAG, "drawChild: child view " + child + " returned null drawing cache");
result = super.drawChild(canvas, child, drawingTime);
}
} else {
if (child.isDrawingCacheEnabled()) {
child.setDrawingCacheEnabled(false);
}
result = super.drawChild(canvas, child, drawingTime);
}
}
canvas.restoreToCount(save);
return result;
}
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
boolean result;
final int save = canvas.save(Canvas.CLIP_SAVE_FLAG);
if (mCanSlide && !lp.slideable && mSlideableView != null) {
// Clip against the slider; no sense drawing what will immediately be covered.
canvas.getClipBounds(mTmpRect);
mTmpRect.right = Math.min(mTmpRect.right, mSlideableView.getLeft());
canvas.clipRect(mTmpRect);
}
if (Build.VERSION.SDK_INT >= 11) { // HC
result = super.drawChild(canvas, child, drawingTime);
} else {
if (lp.dimWhenOffset && mSlideOffset > 0) {
if (!child.isDrawingCacheEnabled()) {
child.setDrawingCacheEnabled(true);
}
final Bitmap cache = child.getDrawingCache();
if (cache != null) {
canvas.drawBitmap(cache, child.getLeft(), child.getTop(), lp.dimPaint);
result = false;
} else {
Log.e(TAG, "drawChild: child view " + child + " returned null drawing cache");
result = super.drawChild(canvas, child, drawingTime);
}
} else {
if (child.isDrawingCacheEnabled()) {
child.setDrawingCacheEnabled(false);
}
result = super.drawChild(canvas, child, drawingTime);
}
}
canvas.restoreToCount(save);
return result;
}
@SuppressLint("WorldWriteableFiles")
public void takeScreenshot(Activity activity)
{
String filename = "screenshot_" + Integer.toString((COUNT_CAPTURED_IMAGES++)) + ".jpg";
FileOutputStream fileOutput = null;
try {
fileOutput = this.context.openFileOutput(filename, Context.MODE_WORLD_WRITEABLE);
ArrayList<View> views = robot.getViews();
if (views != null && views.size() > 0)
{
final View view = views.get(0);
final boolean flag = view.isDrawingCacheEnabled();
activity.runOnUiThread(new Runnable() {
public void run() {
if (!flag) {
view.setDrawingCacheEnabled(true);
}
view.buildDrawingCache();
}
});
this.instrumentation.waitForIdleSync();
Bitmap b = view.getDrawingCache();
b = b.copy(b.getConfig(), false);
activity.runOnUiThread(new Runnable() {
public void run() {
if (!flag) {
view.setDrawingCacheEnabled(false);
}
}
});
if (fileOutput != null) {
b.compress(Bitmap.CompressFormat.JPEG, 90, fileOutput);
Debug.info(this, "Saved image on disk: " + filename);
}
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (fileOutput != null) {
try { fileOutput.close(); } catch(Exception ex) {}
}
}
}
@TargetApi(11)
private void setupChild(View child, int position, int x, boolean flowDown, int childrenTop, boolean selected, boolean recycled) {
boolean isSelected = selected && shouldShowSelector();
boolean updateChildSelected = isSelected != child.isSelected();
int mode = this.mTouchMode;
boolean isPressed = mode > 0 && mode < 3 && this.mMotionPosition == position;
boolean updateChildPressed = isPressed != child.isPressed();
boolean needToMeasure = !recycled || updateChildSelected || child.isLayoutRequested();
LayoutParams p = (LayoutParams) child.getLayoutParams();
if (p == null) {
p = (LayoutParams) generateDefaultLayoutParams();
}
p.viewType = this.mAdapter.getItemViewType(position);
if ((!recycled || p.forceAdd) && !(p.recycledHeaderFooter && p.viewType == -2)) {
p.forceAdd = false;
if (p.viewType == -2) {
p.recycledHeaderFooter = true;
}
addViewInLayout(child, flowDown ? -1 : 0, p, true);
} else {
attachViewToParent(child, flowDown ? -1 : 0, p);
}
if (updateChildSelected) {
child.setSelected(isSelected);
}
if (updateChildPressed) {
child.setPressed(isPressed);
}
if (!(this.mChoiceMode == 0 || this.mCheckStates == null)) {
if (child instanceof Checkable) {
((Checkable) child).setChecked(((Boolean) this.mCheckStates.get(position, Boolean.valueOf(false))).booleanValue());
} else if (VERSION.SDK_INT >= 11) {
child.setActivated(((Boolean) this.mCheckStates.get(position, Boolean.valueOf(false))).booleanValue());
}
}
if (needToMeasure) {
int childWidthSpec;
int childHeightSpec = ViewGroup.getChildMeasureSpec(this.mHeightMeasureSpec, this.mListPadding.top + this.mListPadding.bottom, p.height);
int lpWidth = p.width;
if (lpWidth > 0) {
childWidthSpec = MeasureSpec.makeMeasureSpec(lpWidth, 1073741824);
} else {
childWidthSpec = MeasureSpec.makeMeasureSpec(0, 0);
}
child.measure(childWidthSpec, childHeightSpec);
} else {
cleanupLayoutState(child);
}
int w = child.getMeasuredWidth();
int h = child.getMeasuredHeight();
int childLeft = flowDown ? x : x - w;
if (needToMeasure) {
child.layout(childLeft, childrenTop, childLeft + w, childrenTop + h);
} else {
child.offsetLeftAndRight(childLeft - child.getLeft());
child.offsetTopAndBottom(childrenTop - child.getTop());
}
if (this.mCachingStarted && !child.isDrawingCacheEnabled()) {
child.setDrawingCacheEnabled(true);
}
if (VERSION.SDK_INT >= 11 && recycled && ((LayoutParams) child.getLayoutParams()).scrappedFromPosition != position) {
child.jumpDrawablesToCurrentState();
}
}
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
boolean result;
final int save = canvas.save(Canvas.CLIP_SAVE_FLAG);
if (mCanSlide && !lp.slideable && mSlideableView != null) {
// Clip against the slider; no sense drawing what will immediately be covered.
canvas.getClipBounds(mTmpRect);
if (isLayoutRtlSupport()) {
mTmpRect.left = Math.max(mTmpRect.left, mSlideableView.getRight());
} else {
mTmpRect.right = Math.min(mTmpRect.right, mSlideableView.getLeft());
}
canvas.clipRect(mTmpRect);
}
if (Build.VERSION.SDK_INT >= 11) { // HC
result = super.drawChild(canvas, child, drawingTime);
} else {
if (lp.dimWhenOffset && mSlideOffset > 0) {
if (!child.isDrawingCacheEnabled()) {
child.setDrawingCacheEnabled(true);
}
final Bitmap cache = child.getDrawingCache();
if (cache != null) {
canvas.drawBitmap(cache, child.getLeft(), child.getTop(), lp.dimPaint);
result = false;
} else {
Log.e(TAG, "drawChild: child view " + child + " returned null drawing cache");
result = super.drawChild(canvas, child, drawingTime);
}
} else {
if (child.isDrawingCacheEnabled()) {
child.setDrawingCacheEnabled(false);
}
result = super.drawChild(canvas, child, drawingTime);
}
}
canvas.restoreToCount(save);
return result;
}
/**
* Add a view as a child and make sure it is measured (if necessary) and
* positioned properly.
*
* @param child The view to add
* @param position The position of this child
* @param y The y position relative to which this view will be positioned
* @param flowDown If true, align top edge to y. If false, align bottom edge
* to y.
* @param childrenLeft Left edge where children should be positioned
* @param selected Is this position selected?
* @param recycled Has this view been pulled from the recycle bin? If so it
* does not need to be remeasured.
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void setupChild(View child, int position, int y, boolean flowDown, int childrenLeft,
boolean selected,
boolean recycled) {
final boolean isSelected = selected && shouldShowSelector();
final boolean updateChildSelected = isSelected != child.isSelected();
final int mode = mTouchMode;
final boolean isPressed =
mode > TOUCH_MODE_DOWN && mode < TOUCH_MODE_SCROLL && mMotionPosition == position;
final boolean updateChildPressed = isPressed != child.isPressed();
final boolean needToMeasure = !recycled || updateChildSelected || child.isLayoutRequested();
// Respect layout params that are already in the view. Otherwise make
// some up...
// noinspection unchecked
ZrcAbsListView.LayoutParams p = (ZrcAbsListView.LayoutParams) child.getLayoutParams();
if (p == null) {
p = (ZrcAbsListView.LayoutParams) generateDefaultLayoutParams();
}
p.viewType = mAdapter.getItemViewType(position);
if ((recycled && !p.forceAdd)
|| (p.recycledHeaderFooter &&
p.viewType == ZrcAdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER)) {
attachViewToParent(child, flowDown ? -1 : 0, p);
} else {
p.forceAdd = false;
if (p.viewType == ZrcAdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER) {
p.recycledHeaderFooter = true;
}
addViewInLayout(child, flowDown ? -1 : 0, p, true);
}
if (updateChildSelected) {
child.setSelected(isSelected);
}
if (updateChildPressed) {
child.setPressed(isPressed);
}
if (needToMeasure) {
int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec, mListPadding.left
+ mListPadding.right, p.width);
int lpHeight = p.height;
int childHeightSpec;
if (lpHeight > 0) {
childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
} else {
childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
child.measure(childWidthSpec, childHeightSpec);
} else {
cleanupLayoutState(child);
}
final int w = child.getMeasuredWidth();
final int h = child.getMeasuredHeight();
final int childTop = flowDown ? y : y - h;
if (needToMeasure) {
final int childRight = childrenLeft + w;
final int childBottom = childTop + h;
child.layout(childrenLeft, childTop, childRight, childBottom);
} else {
child.offsetLeftAndRight(childrenLeft - child.getLeft());
child.offsetTopAndBottom(childTop - child.getTop());
}
if (mCachingStarted && !child.isDrawingCacheEnabled()) {
child.setDrawingCacheEnabled(true);
}
if (recycled &&
(((ZrcAbsListView.LayoutParams) child.getLayoutParams()).scrappedFromPosition) !=
position) {
if (Build.VERSION.SDK_INT >= 11) {
child.jumpDrawablesToCurrentState();
}
}
}
/**
* Add a view as a child and make sure it is measured (if necessary) and
* positioned properly.
*
* @param child The view to add
* @param position The position of this child
* @param y The y position relative to which this view will be positioned
* @param flowDown If true, align top edge to y. If false, align bottom
* edge to y.
* @param childrenLeft Left edge where children should be positioned
* @param selected Is this position selected?
* @param recycled Has this view been pulled from the recycle bin? If so it
* does not need to be remeasured.
*/
private void setupChild(View child, int position, int y, boolean flowDown, int childrenLeft,
boolean selected, boolean recycled) {
final boolean isSelected = selected && shouldShowSelector();
final boolean updateChildSelected = isSelected != child.isSelected();
final int mode = mTouchMode;
final boolean isPressed = mode > TOUCH_MODE_DOWN && mode < TOUCH_MODE_SCROLL &&
mMotionPosition == position;
final boolean updateChildPressed = isPressed != child.isPressed();
final boolean needToMeasure = !recycled || updateChildSelected || child.isLayoutRequested();
// Respect layout params that are already in the view. Otherwise make some up...
// noinspection unchecked
LayoutParams p = (LayoutParams) child.getLayoutParams();
if (p == null) {
p = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT, 0);
}
p.viewType = mAdapter.getItemViewType(position);
p.scrappedFromPosition = position;
if ((recycled && !p.forceAdd) || (p.recycledHeaderFooter &&
p.viewType == PLAAdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER)) {
attachViewToParent(child, flowDown ? -1 : 0, p);
} else {
p.forceAdd = false;
if (p.viewType == PLAAdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER) {
p.recycledHeaderFooter = true;
}
addViewInLayout(child, flowDown ? -1 : 0, p, true);
}
if (updateChildSelected) {
child.setSelected(isSelected);
}
if (updateChildPressed) {
child.setPressed(isPressed);
}
if (needToMeasure) {
int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec,
mListPadding.left + mListPadding.right, p.width);
int lpHeight = p.height;
int childHeightSpec;
if (lpHeight > 0) {
childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
} else {
childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
onMeasureChild( child, position, childWidthSpec, childHeightSpec );
//child.measure(childWidthSpec, childHeightSpec);
} else {
cleanupLayoutState(child);
}
final int w = child.getMeasuredWidth();
final int h = child.getMeasuredHeight();
final int childTop = flowDown ? y : y - h;
if (needToMeasure) {
final int childRight = childrenLeft + w;
final int childBottom = childTop + h;
//child.layout(childrenLeft, childTop, childRight, childBottom);
onLayoutChild(child, position, childrenLeft, childTop, childRight, childBottom);
} else {
final int offsetLeft = childrenLeft - child.getLeft();
final int offsetTop = childTop - child.getTop();
onOffsetChild(child, position, offsetLeft, offsetTop);
}
if (mCachingStarted && !child.isDrawingCacheEnabled()) {
child.setDrawingCacheEnabled(true);
}
}
/**
* Add a view as a child and make sure it is measured (if necessary) and
* positioned properly.
*
* @param child The view to add
* @param position The position of this child
* @param y The y position relative to which this view will be positioned
* @param flowDown If true, align top edge to y. If false, align bottom
* edge to y.
* @param childrenLeft Left edge where children should be positioned
* @param selected Is this position selected?
* @param recycled Has this view been pulled from the recycle bin? If so it
* does not need to be remeasured.
*/
private void setupChild(View child, int position, int y, boolean flowDown, int childrenLeft,
boolean selected, boolean recycled) {
final boolean isSelected = selected && shouldShowSelector();
final boolean updateChildSelected = isSelected != child.isSelected();
final int mode = mTouchMode;
final boolean isPressed = mode > TOUCH_MODE_DOWN && mode < TOUCH_MODE_SCROLL &&
mMotionPosition == position;
final boolean updateChildPressed = isPressed != child.isPressed();
final boolean needToMeasure = !recycled || updateChildSelected || child.isLayoutRequested();
// Respect layout params that are already in the view. Otherwise make some up...
// noinspection unchecked
LayoutParams p = (LayoutParams) child.getLayoutParams();
if (p == null) {
p = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT, 0);
}
p.viewType = mAdapter.getItemViewType(position);
p.scrappedFromPosition = position;
if ((recycled && !p.forceAdd) || (p.recycledHeaderFooter &&
p.viewType == PLAAdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER)) {
attachViewToParent(child, flowDown ? -1 : 0, p);
} else {
p.forceAdd = false;
if (p.viewType == PLAAdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER) {
p.recycledHeaderFooter = true;
}
addViewInLayout(child, flowDown ? -1 : 0, p, true);
}
if (updateChildSelected) {
child.setSelected(isSelected);
}
if (updateChildPressed) {
child.setPressed(isPressed);
}
if (needToMeasure) {
int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec,
mListPadding.left + mListPadding.right, p.width);
int lpHeight = p.height;
int childHeightSpec;
if (lpHeight > 0) {
childHeightSpec = View.MeasureSpec.makeMeasureSpec(lpHeight, View.MeasureSpec.EXACTLY);
} else {
childHeightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
}
onMeasureChild( child, position, childWidthSpec, childHeightSpec );
//child.measure(childWidthSpec, childHeightSpec);
} else {
cleanupLayoutState(child);
}
final int w = child.getMeasuredWidth();
final int h = child.getMeasuredHeight();
final int childTop = flowDown ? y : y - h;
if (needToMeasure) {
final int childRight = childrenLeft + w;
final int childBottom = childTop + h;
//child.layout(childrenLeft, childTop, childRight, childBottom);
onLayoutChild(child, position, childrenLeft, childTop, childRight, childBottom);
} else {
final int offsetLeft = childrenLeft - child.getLeft();
final int offsetTop = childTop - child.getTop();
onOffsetChild(child, position, offsetLeft, offsetTop);
}
if (mCachingStarted && !child.isDrawingCacheEnabled()) {
child.setDrawingCacheEnabled(true);
}
}
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
boolean result;
final int save = canvas.save(Canvas.CLIP_SAVE_FLAG);
if (mCanSlide && !lp.slideable && mSlideableView != null) {
// Clip against the slider; no sense drawing what will immediately be covered.
canvas.getClipBounds(mTmpRect);
if (isLayoutRtlSupport()) {
mTmpRect.left = Math.max(mTmpRect.left, mSlideableView.getRight());
} else {
mTmpRect.right = Math.min(mTmpRect.right, mSlideableView.getLeft());
}
canvas.clipRect(mTmpRect);
}
if (Build.VERSION.SDK_INT >= 11) { // HC
result = super.drawChild(canvas, child, drawingTime);
} else {
if (lp.dimWhenOffset && mSlideOffset > 0) {
if (!child.isDrawingCacheEnabled()) {
child.setDrawingCacheEnabled(true);
}
final Bitmap cache = child.getDrawingCache();
if (cache != null) {
canvas.drawBitmap(cache, child.getLeft(), child.getTop(), lp.dimPaint);
result = false;
} else {
Log.e(TAG, "drawChild: child view " + child + " returned null drawing cache");
result = super.drawChild(canvas, child, drawingTime);
}
} else {
if (child.isDrawingCacheEnabled()) {
child.setDrawingCacheEnabled(false);
}
result = super.drawChild(canvas, child, drawingTime);
}
}
canvas.restoreToCount(save);
return result;
}
/**
* Add a view as a child and make sure it is measured (if necessary) and positioned properly.
*
* @param child
* The view to add
* @param position
* The position of this child
* @param x
* The x position relative to which this view will be positioned
* @param flowDown
* If true, align left edge to x. If false, align right edge to x.
* @param childrenTop
* Top edge where children should be positioned
* @param selected
* Is this position selected?
* @param recycled
* Has this view been pulled from the recycle bin? If so it does not need to be remeasured.
*/
private void setupChild( View child, int position, int x, boolean flowDown, int childrenTop, boolean selected, boolean recycled ) {
final boolean isSelected = selected && shouldShowSelector();
final boolean updateChildSelected = isSelected != child.isSelected();
final int mode = mTouchMode;
final boolean isPressed = mode > TOUCH_MODE_DOWN && mode < TOUCH_MODE_SCROLL && mMotionPosition == position;
final boolean updateChildPressed = isPressed != child.isPressed();
final boolean needToMeasure = !recycled || updateChildSelected || child.isLayoutRequested();
// Respect layout params that are already in the view. Otherwise make some up...
// noinspection unchecked
AbsHListView.LayoutParams p = (AbsHListView.LayoutParams) child.getLayoutParams();
if ( p == null ) {
p = (AbsHListView.LayoutParams) generateDefaultLayoutParams();
}
p.viewType = mAdapter.getItemViewType( position );
if ( ( recycled && !p.forceAdd ) || ( p.recycledHeaderFooter && p.viewType == AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER ) ) {
attachViewToParent( child, flowDown ? -1 : 0, p );
} else {
p.forceAdd = false;
if ( p.viewType == AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER ) {
p.recycledHeaderFooter = true;
}
addViewInLayout( child, flowDown ? -1 : 0, p, true );
}
if ( updateChildSelected ) {
child.setSelected( isSelected );
}
if ( updateChildPressed ) {
child.setPressed( isPressed );
}
if ( mChoiceMode != ListView.CHOICE_MODE_NONE && mCheckStates != null ) {
if ( child instanceof Checkable ) {
( (Checkable) child ).setChecked( mCheckStates.get( position ) );
} else if ( android.os.Build.VERSION.SDK_INT >= 11 ) {
child.setActivated( mCheckStates.get( position ) );
}
}
if ( needToMeasure ) {
int childHeightSpec = ViewGroup.getChildMeasureSpec( mHeightMeasureSpec, mListPadding.top + mListPadding.bottom, p.height );
int lpWidth = p.width;
int childWidthSpec;
if ( lpWidth > 0 ) {
childWidthSpec = MeasureSpec.makeMeasureSpec( lpWidth, MeasureSpec.EXACTLY );
} else {
childWidthSpec = MeasureSpec.makeMeasureSpec( 0, MeasureSpec.UNSPECIFIED );
}
child.measure( childWidthSpec, childHeightSpec );
} else {
cleanupLayoutState( child );
}
final int w = child.getMeasuredWidth();
final int h = child.getMeasuredHeight();
final int childLeft = flowDown ? x : x - w;
if ( needToMeasure ) {
final int childBottom = childrenTop + h;
final int childRight = childLeft + w;
child.layout( childLeft, childrenTop, childRight, childBottom );
} else {
child.offsetLeftAndRight( childLeft - child.getLeft() );
child.offsetTopAndBottom( childrenTop - child.getTop() );
}
if ( mCachingStarted && !child.isDrawingCacheEnabled() ) {
child.setDrawingCacheEnabled( true );
}
if( android.os.Build.VERSION.SDK_INT >= 11 ) {
if ( recycled && ( ( (AbsHListView.LayoutParams) child.getLayoutParams() ).scrappedFromPosition ) != position ) {
child.jumpDrawablesToCurrentState();
}
}
}
/**
* Add a view as a child and make sure it is measured (if necessary) and
* positioned properly.
*
* @param child The view to add
* @param position The position of this child
* @param y The y position relative to which this view will be positioned
* @param flowDown If true, align top edge to y. If false, align bottom edge
* to y.
* @param childrenLeft Left edge where children should be positioned
* @param selected Is this position selected?
* @param recycled Has this view been pulled from the recycle bin? If so it
* does not need to be remeasured.
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void setupChild(View child, int position, int y, boolean flowDown, int childrenLeft,
boolean selected,
boolean recycled) {
final boolean isSelected = selected && shouldShowSelector();
final boolean updateChildSelected = isSelected != child.isSelected();
final int mode = mTouchMode;
final boolean isPressed =
mode > TOUCH_MODE_DOWN && mode < TOUCH_MODE_SCROLL && mMotionPosition == position;
final boolean updateChildPressed = isPressed != child.isPressed();
final boolean needToMeasure = !recycled || updateChildSelected || child.isLayoutRequested();
// Respect layout params that are already in the view. Otherwise make
// some up...
// noinspection unchecked
ZrcAbsListView.LayoutParams p = (ZrcAbsListView.LayoutParams) child.getLayoutParams();
if (p == null) {
p = (ZrcAbsListView.LayoutParams) generateDefaultLayoutParams();
}
p.viewType = mAdapter.getItemViewType(position);
if ((recycled && !p.forceAdd)
|| (p.recycledHeaderFooter &&
p.viewType == ZrcAdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER)) {
attachViewToParent(child, flowDown ? -1 : 0, p);
} else {
p.forceAdd = false;
if (p.viewType == ZrcAdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER) {
p.recycledHeaderFooter = true;
}
addViewInLayout(child, flowDown ? -1 : 0, p, true);
}
if (updateChildSelected) {
child.setSelected(isSelected);
}
if (updateChildPressed) {
child.setPressed(isPressed);
}
if (needToMeasure) {
int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec, mListPadding.left
+ mListPadding.right, p.width);
int lpHeight = p.height;
int childHeightSpec;
if (lpHeight > 0) {
childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
} else {
childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
child.measure(childWidthSpec, childHeightSpec);
} else {
cleanupLayoutState(child);
}
final int w = child.getMeasuredWidth();
final int h = child.getMeasuredHeight();
final int childTop = flowDown ? y : y - h;
if (needToMeasure) {
final int childRight = childrenLeft + w;
final int childBottom = childTop + h;
child.layout(childrenLeft, childTop, childRight, childBottom);
} else {
child.offsetLeftAndRight(childrenLeft - child.getLeft());
child.offsetTopAndBottom(childTop - child.getTop());
}
if (mCachingStarted && !child.isDrawingCacheEnabled()) {
child.setDrawingCacheEnabled(true);
}
if (recycled &&
(((ZrcAbsListView.LayoutParams) child.getLayoutParams()).scrappedFromPosition) !=
position) {
if (APIUtil.isSupport(11)) {
child.jumpDrawablesToCurrentState();
}
}
}