getchildbynamedrawingorder什么时候调用

java - getChildDrawingOrder called/used erratically? - Stack Overflow
to customize your list.
Join the Stack Overflow Community
Stack Overflow is a community of 6.4 million programmers, just like you, helping each other.
J it only takes a minute:
I am creating an isometric map with simple tiles, and I&ve extended RelativeLayout to create a layout that holds these tiles. Really, just using a RelativeLayout as-is worked fine as long as my orientation matched the order in which the tiles were written to the XML all I&ve overwritten are the constructors, where I simply call super and setChildrenDrawingOrderEnabled(true); along with setting up some variables (height and width of the grid), and then getChildDrawingOrder itself.
My code for getChildDrawingOrder figures out the new index for the given child, and also sets a string in the child to i-&i', where i is the original index and i' is the new index. I&m us the children are set to draw this string on themselves along with their coordinates.
Unfortunately, it does not work correctly, or rather it works erratically. Of the nine tiles in my test case, three don&t seem to have getChildDrawingOrder called at all: the string I mentioned above is null. Of the rest, at least one is being drawn out of order despite getting the correct index passed to it.
Here&s a picture (in the TOP orientation):
Notice that (0,2), (1,2), and (2,1) are all listed as NULL, and therefore getChildDrawingOrder appears to have never been called for them. Also note that (1,0) is drawn on top of (1,1), even though both its i (3) and i' (1) are less than (1,1)&s (4 and 4, respectively).
Here&s the code from getChildDrawingOrder:
protected int getChildDrawingOrder(int childCount, int i)
TileView ch = (TileView)getChildAt(i);
ch.order = "Called"; // this string is drawn on my children
int gx, // the "true" x,y for the current rotation,
// where 0,0 is the top corner
switch (rotation)
gx = ch.x();
gy = ch.y();
case LEFT:
gx = (width()-1-ch.x());
gy = ch.y();
case RIGHT:
gx = ch.x();
gy = (length()-1-ch.y());
case BOTTOM:
gx = (width()-1-ch.x());
gy = (length()-1-ch.y());
gx = ch.x();
gy = ch.y();
int row = gx+ // current row
if ( row == 0 ) // row 0 is always just the top corner and 0
ch.order = new String(i+"-&0"); // string set to i-&i'
int mx = width()-1, // maximum x value
my = length()-1, // maximum y value
mrow = mx+my, // maximum row
min = Math.min(mx, my), // minor axis length
maj = Math.max(mx, my), // major axis length
// for storing the return value
// inside the top corner
if ( row &= min )
// Gauss's formula to get number of cells in previous rows
// plus the number for which cell in this row this is.
retn = row*(row+1)/2+
// in the middle
else if ( row &= maj )
// Gauss's formula to get number of cells in top corner
// plus the number of cells in previous rows of the middle section
// plus the number for which cell in this row this is.
retn = min*(min+1)/2+min*(row-min)+
// bottom corner
retn = (min+1)*(min+2)/2 // cells in the top corner
+ min*(maj-min) // cells in the middle
+ (mrow-maj)*(mrow-maj+1)/2 // total cells in bottom triangle
- (mrow-row+1)*(mrow-row+2)/2 // less cells after this one
+ gy // which cell in this row
- (row-maj) // to account for gy not starting at zero
ch.order = new String(i+"-&"+retn); // string set to i-&i'
Can anyone shed some light on what&s going on? Why isn&t getChildDrawingOrder being called for those three tiles? Why is (1,0) drawn in the wrong order, even though getChildDrawingOrder is called on it?
3,52912447
OK, figured it out by looking at the Android source code. I had the mapping of getChildDrawingOrder: the i passed is &which child should I draw i th?& not "when should I draw child i?" The reason for the NULLs is because those children were being drawn before their own i was passed.
I changed my code to figure out the order for all children during the onMeasure pass, saving that in a SparseIntArray, and then just returned that from getChildDrawingOrder. This works.
Back-calculating the index in the getChildDrawingOrder function, by the way, is a bad idea unless you want to rely on the order in which the children are declared. Because if you don&t rely on that order, you have to walk through the list of children to find the one that has the appropriate x and y values, which means you have to walk through the list of children for each child. That&s an O(n?) operation (read: fairly inefficient). The mathematics are also reasonably complicated.
3,52912447
Your Answer
Sign up or
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Post as a guest
By posting your answer, you agree to the
Not the answer you're looking for?
Browse other questions tagged
Stack Overflow works best with JavaScript enabled为了账号安全,请及时绑定邮箱和手机
Android TV 重写GridView,实现焦点放大效果
Android TV 重写GridView,实现焦点放大效果
关于缩放,使用了view.setScaleX/Y 方法,api11以上即可。
重写dispatchDraw(),绘制选中项的焦点效果。(注意带阴影的焦点图需要微调偏移量)
要将选中项绘制显示在顶层,所以要改变GridView的子View绘制顺序;
所以要重写bringChildToFront、getChildDrawingOrder,同时要打开setChildrenDrawingOrderEnabled(true)。
在缩放代码中添加了监听器,用于调用端,设置回调。
注意: 如果GridView的最后一行的个数少于列数,在较少的列上向下,会报异常。 还有就是当快速切换时,可能会看到默认的listSelector,可以将其设置为透明的。
package com.stone.tvapplication.
import android.content.C
import android.content.res.TypedA
import android.graphics.C
import android.graphics.C
import android.graphics.R
import android.graphics.drawable.D
import android.util.AttributeS
import android.view.V
import android.view.ViewG
import android.widget.AbsListV
import android.widget.GridV
import android.widget.ImageV
import android.widget.RelativeL
import android.widget.TextV
import com.stone.tvapplication.R;
import com.stone.tvapplication.util.AdaptionA
* 重写dispatchDraw,在选中项上绘制一个focus-drawable
* author : stone
: 16/5/11 10 20
public class TvFocusGridView extends GridView {
private Drawable mFocusBackD
private Rect mFocusBackR
private int mSelectedP
private View mSelectedV
private float mScaleX;
private float mScaleY;
private onItemFocusSelectedListener mOnItemFocusSelectedL
public TvFocusGridView(Context context) {
this(context, null);
public TvFocusGridView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
public TvFocusGridView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setClipChildren(false);
setClipToPadding(false);
setChildrenDrawingOrderEnabled(true);//设置绘制顺序可重定义,需要重写getChildDrawingOrder来变化绘制顺序
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.TvFocusGridView);
mFocusBackDrawable = array.getDrawable(R.styleable.TvFocusGridView_focus_background);
array.recycle();
mFocusBackRect = new Rect();
mFocusBackDrawable.getPadding(mFocusBackRect); //Drawable中实际填充图像的Rect
System.out.println("mFocusBackRect--&" + mFocusBackRect);
public interface onItemFocusSelectedListener {
void onFocused(View child, int position);
void unfocused(View child, int position);
public void setOnItemFocusSelectedListener(onItemFocusSelectedListener onItemFocusSelectedListener) {
this.mOnItemFocusSelectedListener = onItemFocusSelectedL
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
if (mFocusBackDrawable == null) {
drawSelector(canvas);
private void drawSelector(Canvas canvas) {
View view = getSelectedView();
if (view == null)
bringChildToFront(view);
if (isFocused()) {
scaleSelectedView(view);
Rect gvVisibleRect = new Rect();
this.getGlobalVisibleRect(gvVisibleRect); //GridView可见区 在屏幕中的绝对坐标 rect
Rect selectedViewRect = new Rect();
if (mSelectedView instanceof ViewGroup) {
mSelectedView.getGlobalVisibleRect(selectedViewRect); //选中View可见区 在屏幕中的绝对坐标 rect
selectedViewRect.offset(-gvVisibleRect.left, - gvVisibleRect.top); //偏移
selectedViewRect.left -= mFocusBackRect.left +
40;//+阴影偏移
selectedViewRect.top -= mFocusBackRect.top + 20;
selectedViewRect.right += mFocusBackRect.right + 40;
selectedViewRect.bottom += mFocusBackRect.bottom + 20;
mFocusBackDrawable.setBounds(selectedViewRect);
mFocusBackDrawable.draw(canvas);
* 使子view位置在上层
* @param child
public void bringChildToFront(View child) { //重写,不调用父类方法;获取child的实际position
super.bringChildToFront(child);
mSelectedPosition = indexOfChild(child);
invalidate();
protected int getChildDrawingOrder(int childCount, int i) {//交换 选中项与最后一项 绘制的顺序
if (mSelectedPosition != AbsListView.INVALID_POSITION) {
if (i == mSelectedPosition) {
return childCount - 1;
if (i == childCount - 1) {
return mSelectedP
return super.getChildDrawingOrder(childCount, i);
private void scaleSelectedView(View view) {//缩放
unScalePreView();
mSelectedView =
mSelectedView.setScaleX(mScaleX); //api11
mSelectedView.setScaleY(mScaleY);
if (mOnItemFocusSelectedListener != null) {
mOnItemFocusSelectedListener.onFocused(mSelectedView, indexOfChild(mSelectedView));
private void unScalePreView() {//还原
if (mSelectedView != null) {
mSelectedView.setScaleX(1);
mSelectedView.setScaleY(1);
if (mOnItemFocusSelectedListener != null) {
mOnItemFocusSelectedListener.unfocused(mSelectedView, indexOfChild(mSelectedView));
mSelectedView =
protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {//整个GridView焦点状态
if (!gainFocus) {
unScalePreView();
requestLayout();
super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
public void setScale(float scaleX, float scaleY) {
this.mScaleX = scaleX;
this.mScaleY = scaleY;
调用端设置与监听:
mGridView.setAdapter(mAdapter);
mGridView.setScale(1.2f, 1.2f);
mGridView.setHorizontalSpacing(AdaptionAlgo.scaleX(30));
mGridView.setVerticalSpacing(AdaptionAlgo.scaleY(30));
mGridView.setPadding(60, 40, 60, 40);
mGridView.setOnItemFocusSelectedListener(new TvFocusGridView.onItemFocusSelectedListener() {
public void onFocused(View child, int position) {
TextView tv = getViewById(child, R.id.tv_text);
tv.setTextColor(Color.RED);
public void unfocused(View child, int position) {
TextView tv = getViewById(child, R.id.tv_text);
tv.setTextColor(Color.MAGENTA);
核心代码出自:
相关标签:
分享即可 +1积分
请登录后,发表评论
评论(Enter+Ctrl)
评论加载中...
评论加载中...
移动开发工程师
人生不是简单的if和else,很多时候都是在出现问题时才when and then
作者的热门手记
Copyright (C)
All Rights Reserved | 京ICP备 号-2Android之gallery 常见2种使用方法和3D效果总结
我们有时候在iPhone手机上或者Windows上面看到动态的图片,可以通过鼠标或者手指触摸来移动它,产生动态的图片滚动效果,还可以根据你的点击或者触摸触发其他事件响应。同样的,在Android中也提供这这种实现,这就是通过Gallery在UI上实现缩略图浏览器。
一般情况下,我们在Android中要用到类似这种图片容器的控件,都需要为它指定一个适配器,让它可以把内容按照我们定义的方式来显示,因此我们来给它加一个适配器,至于这个适配器如何实现,后面接着来操作,这里只需知道这个适配器的类叫ImageGalleryAdapter 。 gallery.setAdapter(new ImageGalleryAdapter (this));
下面介绍常用2种用法:
第一种方法:
第一步:设计xml布局文件
代码如下:main.xml
&LinearLayout xmlns:android=&/apk/res/android&
android:layout_width=&fill_parent&
android:layout_height=&fill_parent&
android:orientation=&vertical& &
android:id=&@+id/myGallery&
android:layout_width=&fill_parent&
android:layout_height=&wrap_content&
android:gravity=&center_vertical&
android:spacing=&3px&
android:text=&@string/hello& /&
&/LinearLayout&
第二步:自定义一个适配器,这个适配器继承BaseAdapter这个类
代码如下:
package net.loonggg.
import android.content.C
import android.view.V
import android.view.ViewG
import android.view.ViewGroup.LayoutP
import android.widget.BaseA
import android.widget.G
import android.widget.ImageV
public class ImageGalleryAdapter extends BaseAdapter {
// 里面所有的方法表示的是可以根据指定的显示图片的数量,进行每个图片的处理
private int[] image = new int[] { R.drawable.ispic_a, R.drawable.ispic_b,
R.drawable.ispic_c, R.drawable.ispic_d, R.drawable.ispic_e };
public ImageGalleryAdapter(Context context) {
this.context =
public int getCount() { // 取得要显示内容的数量
return image.
public Object getItem(int position) { // 每个资源的位置
return image[position];
public long getItemId(int position) { // 取得每个项的ID
return image[position];
// 将资源设置到一个组件之中,很明显这个组件是ImageView
public View getView(int position, View convertView, ViewGroup parent) {
ImageView iv = new ImageView(context);
iv.setBackgroundColor(0xFFFFFFFF);
iv.setImageResource(image[position]);// 给ImageView设置资源
iv.setScaleType(ImageView.ScaleType.CENTER);// 设置对齐方式
iv.setLayoutParams(new Gallery.LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
}第三步:主方法:
package net.loonggg.
import android.app.A
import android.os.B
import android.view.V
import android.widget.AdapterV
import android.widget.AdapterView.OnItemClickL
import android.widget.G
import android.widget.T
public class GalleryActivity extends Activity {
private Gallery myG
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myGallery = (Gallery) findViewById(R.id.myGallery);
myGallery.setAdapter(new ImageGalleryAdapter(this));
myGallery.setOnItemClickListener(new OnItemClickListenerImpl());
private class OnItemClickListenerImpl implements OnItemClickListener {
public void onItemClick(AdapterView&?& parent, View view, int position,
long id) {
Toast.makeText(GalleryActivity.this, String.valueOf(position),
Toast.LENGTH_SHORT).show();
第二种方法
第一步:设计xml布局文件&
代码如下:main.xml
&?xml version=&1.0& encoding=&utf-8&?&
&LinearLayout xmlns:android=&/apk/res/android&
android:layout_width=&fill_parent&
android:layout_height=&fill_parent&
android:gravity=&bottom&
android:orientation=&vertical& &
&ImageSwitcher
android:id=&@+id/is&
android:layout_width=&fill_parent&
android:layout_height=&wrap_content& &
&/ImageSwitcher&
android:id=&@+id/myGallery&
android:layout_width=&fill_parent&
android:layout_height=&wrap_content&
android:gravity=&center_vertical&
android:spacing=&3px& /&
&/LinearLayout&
gallery_item.xml文件:
代码如下:
&?xml version=&1.0& encoding=&utf-8&?&
&LinearLayout xmlns:android=&/apk/res/android&
android:layout_width=&wrap_content&
android:layout_height=&wrap_content&
android:background=&#FFFFFF&
android:orientation=&horizontal& &
&ImageView
android:id=&@+id/iv&
android:layout_width=&wrap_content&
android:layout_height=&wrap_content&
android:scaleType=&center& /&
&/LinearLayout&
第二步:MainActivity
代码如下:
package net.loonggg.gallery2;
import java.lang.reflect.F
import java.util.ArrayL
import java.util.HashM
import java.util.L
import java.util.M
import android.app.A
import android.os.B
import android.view.V
import android.view.ViewGroup.LayoutP
import android.widget.AdapterV
import android.widget.AdapterView.OnItemClickL
import android.widget.G
import android.widget.ImageS
import android.widget.ImageV
import android.widget.SimpleA
import android.widget.ViewSwitcher.ViewF
public class MainActivity extends Activity {
private ImageS
private SimpleA
private List&Map&String, Integer&& list = new ArrayList&Map&String, Integer&&();
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
is = (ImageSwitcher) findViewById(R.id.is);
is.setFactory(new ViewFactoryImpl());
initAdapter();
gallery = (Gallery) findViewById(R.id.myGallery);
gallery.setAdapter(adapter); // 为gallery设置合适的适配器
gallery.setOnItemClickListener(new OnItemClickListenerImpl());
public class OnItemClickListenerImpl implements OnItemClickListener { // gallery的点击事件
public void onItemClick(AdapterView&?& parent, View view, int position,
long id) {
Map&String, Integer& map = (Map&String, Integer&) parent
.getAdapter().getItem(position);
is.setImageResource(map.get(&image&));
public void initAdapter() { // 这个方法的功能是:从R.java文件中获取图片资源的id,如果资源图片数量比较多,用数组的方法一一定义,就不太合适,这种方法最好了。
Field[] fields = R.drawable.class.getDeclaredFields();
for (int x = 0; x & fields. x++) {
if (fields[x].getName().startsWith(&ispic_&)) { // 根据图片的名称取出想要的图片
Map&String, Integer& map = new HashMap&String, Integer&();
map.put(&image&, fields[x].getInt(R.drawable.class));
} catch (Exception e) {
e.printStackTrace();
list.add(map);
adapter = new SimpleAdapter(MainActivity.this, list,
R.layout.grid_item, new String[] { &image& },
new int[] { R.id.iv });
public class ViewFactoryImpl implements ViewFactory {
public View makeView() {
ImageView iv = new ImageView(MainActivity.this);
iv.setBackgroundColor(0xFFFFFFFF);
iv.setScaleType(ImageView.ScaleType.CENTER);
iv.setLayoutParams(new ImageSwitcher.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
Android gallery 3D效果
一 &创建倒影效果
二 扩装gallery&
三 完整代码
先看效果,不然就是无图无真相了。
一,创建倒影效果
这个基本思路是:
1,创建一个源图一样的图,利用martrix将图片旋转180度。这个倒影图的高是源图的一半。
Matrix matrix = new Matrix();
// 1表示放大比例,不放大也不缩小。
// -1表示在y轴上相反,即旋转180度。
matrix.preScale(1, -1);
Bitmap reflectionBitmap = Bitmap.createBitmap(
srcBitmap,
srcBitmap.getHeight() / 2,
// top为源图的一半
srcBitmap.getWidth(),
// 宽度与源图一样
srcBitmap.getHeight() / 2,
// 高度与源图的一半
false);2,创建一个最终效果的图,即源图 + 间隙 + 倒影。
final int REFLECTION_GAP = 5;
Bitmap bitmapWithReflection = Bitmap.createBitmap(
reflectionWidth,
srcHeight + reflectionHeight + REFLECTION_GAP,
Config.ARGB_8888);
3,依次将源图、倒影图绘制在最终的bitmap上面。
Canvas canvas = new Canvas(bitmapWithReflection);
// Draw the original bitmap.
canvas.drawBitmap(srcBitmap, 0, 0, null);
// Draw the reflection bitmap.
canvas.drawBitmap(reflectionBitmap, 0, srcHeight + REFLECTION_GAP, null);4,创建LinearGradient,从而给定一个由上到下的渐变色。
Paint paint = new Paint();
paint.setAntiAlias(true);
LinearGradient shader = new LinearGradient(
srcHeight,
bitmapWithReflection.getHeight() + REFLECTION_GAP,
0x70FFFFFF,
0x00FFFFFF,
TileMode.MIRROR);
paint.setShader(shader);
paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.DST_IN));
// Draw the linear shader.
canvas.drawRect(
srcHeight,
bitmapWithReflection.getHeight() + REFLECTION_GAP,
二,扩展Gallery
扩展系统的gallery,我们需要重写两个方法,getChildStaticTransformation()和getChildDrawingOrder(),同时,要使这两个方法能被调用,必须执行如下两行代码,文档上面是有说明的。
// Enable set transformation.
this.setStaticTransformationsEnabled(true);
// Enable set the children drawing order.
this.setChildrenDrawingOrderEnabled(true);
getChildDrawingOrder的实现
protected int getChildDrawingOrder(int childCount, int i)
// Current selected index.
int selectedIndex = getSelectedItemPosition() - getFirstVisiblePosition();
if (selectedIndex & 0)
if (i & selectedIndex)
else if (i &= selectedIndex)
return childCount - 1 - i + selectedI
这里为什么要计算drawing order,因为从上图中看到,我们的效果是:中间左边的顺序是 0, 1, 2,右边的child覆盖左边的child,而在中间右边的顺序正好相反,左边的覆盖右边的,所以我们要重写这个方法,而gallery自身的实现,不是这种效果。
getChildStaticTransformation的实现
这个方法就是根据child来计算它的transformation(变换),我们需要去修改它里面的matrix,从而达到旋转的效果。根据位置和角度来计算的matrix的方法写在另外一个方法transformImageBitmap中实现。
transformImageBitmap()的实现
private void transformImageBitmap(View child, Transformation t, int rotationAngle)
mCamera.save();
final Matrix imageMatrix = t.getMatrix();
final int imageHeight = child.getHeight();
final int imageWidth
= child.getWidth();
final int rotation
= Math.abs(rotationAngle);
// Zoom on Z axis.
mCamera.translate(0, 0, mMaxZoom);
if (rotation & mMaxRotationAngle)
float zoomAmount = (float)(mMaxZoom + rotation * 1.5f);
mCamera.translate(0, 0, zoomAmount);
// Rotate the camera on Y axis.
mCamera.rotateY(rotationAngle);
// Get the matrix from the camera, in fact, the matrix is S (scale) transformation.
mCamera.getMatrix(imageMatrix);
// The matrix final is T2 * S * T1, first translate the center point to (0, 0),
// then scale, and then translate the center point to its original point.
// T * S * T
imageMatrix.postTranslate((imageWidth / 2), (imageHeight / 2));
// (T2 * S) * T1
imageMatrix.preTranslate(-(imageWidth / 2), -(imageHeight / 2));
mCamera.restore();
这里,简单说明一个,
&&&&&&& 第一,先在Z轴上平称,其实就是得到一个缩放矩阵变换,我这里简写为 S。
&&&&&&& 第二,是利用camera这个类来生成matrix,其实mCamera.rotateY就是围绕Y轴旋转。这里生成了一个旋转矩阵,记为 R 。经过这两步,此时调用mCamera.getMatrix(imageMatrix); 从Camera中得到matrix,此时这个矩阵中包含了S * R。
&&&&&&& 第三,最关键是下面两句 & & &&
imageMatrix.postTranslate((imageWidth / 2), (imageHeight / 2));
// (T2 * S) * T1
imageMatrix.preTranslate(-(imageWidth / 2), -(imageHeight / 2));
& 由于这里涉及到旋转与缩放,缩放操作其实应该是针对Child中点进行了,这里就是作一个平衡操作,我们必须是先平移,再缩放,再平移回原来位置,所以,我们最终的矩阵变换应该是这样的:
&&&&&&& M = T * (S * R) * T1&& (这里在T1表示与T相反)。
三,完整代码
GalleryFlow.java
import android.content.C
import android.graphics.C
import android.graphics.M
import android.util.AttributeS
import android.view.V
import android.view.animation.T
import android.widget.G
public class GalleryFlow extends Gallery
* The camera class is used to 3D transformation matrix.
private Camera mCamera = new Camera();
* The max rotation angle.
private int mMaxRotationAngle = 60;
* The max zoom value (Z axis).
private int mMaxZoom = -120;
* The center of the gallery.
private int mCoveflowCenter = 0;
public GalleryFlow(Context context)
this(context, null);
public GalleryFlow(Context context, AttributeSet attrs)
this(context, attrs, 0);
public GalleryFlow(Context context, AttributeSet attrs, int defStyle)
super(context, attrs, defStyle);
// Enable set transformation.
this.setStaticTransformationsEnabled(true);
// Enable set the children drawing order.
this.setChildrenDrawingOrderEnabled(true);
public int getMaxRotationAngle()
return mMaxRotationA
public void setMaxRotationAngle(int maxRotationAngle)
mMaxRotationAngle = maxRotationA
public int getMaxZoom()
return mMaxZ
public void setMaxZoom(int maxZoom)
mMaxZoom = maxZ
protected int getChildDrawingOrder(int childCount, int i)
// Current selected index.
int selectedIndex = getSelectedItemPosition() - getFirstVisiblePosition();
if (selectedIndex & 0)
if (i & selectedIndex)
else if (i &= selectedIndex)
return childCount - 1 - i + selectedI
protected void onSizeChanged(int w, int h, int oldw, int oldh)
mCoveflowCenter = getCenterOfCoverflow();
super.onSizeChanged(w, h, oldw, oldh);
private int getCenterOfView(View view)
return view.getLeft() + view.getWidth() / 2;
protected boolean getChildStaticTransformation(View child, Transformation t)
super.getChildStaticTransformation(child, t);
final int childCenter = getCenterOfView(child);
final int childWidth
= child.getWidth();
int rotationAngle = 0;
t.clear();
t.setTransformationType(Transformation.TYPE_MATRIX);
// If the child is in the center, we do not rotate it.
if (childCenter == mCoveflowCenter)
transformImageBitmap(child, t, 0);
// Calculate the rotation angle.
rotationAngle = (int)(((float)(mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle);
// Make the angle is not bigger than maximum.
if (Math.abs(rotationAngle) & mMaxRotationAngle)
rotationAngle = (rotationAngle & 0) ? -mMaxRotationAngle : mMaxRotationA
transformImageBitmap(child, t, rotationAngle);
private int getCenterOfCoverflow()
return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2 + getPaddingLeft();
private void transformImageBitmap(View child, Transformation t, int rotationAngle)
mCamera.save();
final Matrix imageMatrix = t.getMatrix();
final int imageHeight = child.getHeight();
final int imageWidth
= child.getWidth();
final int rotation
= Math.abs(rotationAngle);
// Zoom on Z axis.
mCamera.translate(0, 0, mMaxZoom);
if (rotation & mMaxRotationAngle)
float zoomAmount = (float)(mMaxZoom + rotation * 1.5f);
mCamera.translate(0, 0, zoomAmount);
// Rotate the camera on Y axis.
mCamera.rotateY(rotationAngle);
// Get the matrix from the camera, in fact, the matrix is S (scale) transformation.
mCamera.getMatrix(imageMatrix);
// The matrix final is T2 * S * T1, first translate the center point to (0, 0),
// then scale, and then translate the center point to its original point.
// T * S * T
imageMatrix.postTranslate((imageWidth / 2), (imageHeight / 2));
// (T2 * S) * T1
imageMatrix.preTranslate(-(imageWidth / 2), -(imageHeight / 2));
mCamera.restore();
}BitmapUtil.java
package com.lee.gallery3d.
import android.graphics.B
import android.graphics.Bitmap.C
import android.graphics.C
import android.graphics.LinearG
import android.graphics.M
import android.graphics.P
import android.graphics.PixelF
import android.graphics.PorterDuffX
import android.graphics.Shader.TileM
import android.graphics.drawable.D
public class BitmapUtil
public static Bitmap createReflectedBitmap(Bitmap srcBitmap)
if (null == srcBitmap)
// The gap between the reflection bitmap and original bitmap.
final int REFLECTION_GAP = 4;
int srcWidth
= srcBitmap.getWidth();
int srcHeight = srcBitmap.getHeight();
int reflectionWidth
= srcBitmap.getWidth();
int reflectionHeight = srcBitmap.getHeight() / 2;
if (0 == srcWidth || srcHeight == 0)
// The matrix
Matrix matrix = new Matrix();
matrix.preScale(1, -1);
// The reflection bitmap, width is same with original's, height is half of original's.
Bitmap reflectionBitmap = Bitmap.createBitmap(
srcBitmap,
srcHeight / 2,
srcHeight / 2,
if (null == reflectionBitmap)
// Create the bitmap which contains original and reflection bitmap.
Bitmap bitmapWithReflection = Bitmap.createBitmap(
reflectionWidth,
srcHeight + reflectionHeight + REFLECTION_GAP,
Config.ARGB_8888);
if (null == bitmapWithReflection)
// Prepare the canvas to draw stuff.
Canvas canvas = new Canvas(bitmapWithReflection);
// Draw the original bitmap.
canvas.drawBitmap(srcBitmap, 0, 0, null);
// Draw the reflection bitmap.
canvas.drawBitmap(reflectionBitmap, 0, srcHeight + REFLECTION_GAP, null);
Paint paint = new Paint();
paint.setAntiAlias(true);
LinearGradient shader = new LinearGradient(
srcHeight,
bitmapWithReflection.getHeight() + REFLECTION_GAP,
0x70FFFFFF,
0x00FFFFFF,
TileMode.MIRROR);
paint.setShader(shader);
paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.DST_IN));
// Draw the linear shader.
canvas.drawRect(
srcHeight,
bitmapWithReflection.getHeight() + REFLECTION_GAP,
return bitmapWithR
catch (Exception e)
e.printStackTrace();
> 本站内容系网友提交或本网编辑转载,其目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请及时与本网联系,我们将在第一时间删除内容!
实验目的:熟悉ospf的3种认证方法和2种认证方式 使用拓扑: 在接口上做认证: R3: interface Serial1/1 ip address 10.1.34.3 255.255.255.0 ip ospf authentication //启用认证,如果不打这个命令的话,密码是不其作用的. ip ospf authentication-key ci ...
第一种方法: 第一步:设计xml布局文件
代码如下:main.xm &?xml version=&1.0& encoding=&utf-8&?& &LinearLayout xmlns:android=&/apk/res/android& ...
今天在做数据库升级的时候,遇到一个问题,就是onCreate方法和onUpgrade方法的执行时机的问题,这个当时在操作的时候,没有弄清楚,很是迷糊,所以写代码的时候出现了很多的问题,所以没办法就去扒源代码看了.不过在此之前我讲解过一篇关于数据库升级的文章,但是那里没有详细的讲解一下这两个方法的执行时机,所以这里就在单独说一下关于数据库升级的文章:http: ...
C#窗体间通讯的几种处理方法 应用程序开发中,经常需要多窗体之间进行数据通信,写几个例子,把几种常用的通信方式总结一下: 现有两个窗体,如frmMain和frmFTP..我想在frmMain窗体中取得frmFTP窗体中输入的FTP参数,如FTP的主机名,端口号,用户名和密码,之间如何通信? 下面是frmFTP窗体的代码:
public pa ...
Android 系统自带Gallery选中Item默认是居中显示,这样有时候左边空出一大块,非常不美观,网上已有不少人解决了这个问题,比如这篇blog中提到的方法 http://blog.csdn.net/luinsist/article/details/8205638,这样有个问题是每次点击item都会滑动到最左边,如果要跳转界面的话会觉得有点迟钝,能不能 ...
上一篇文章中,我为大家介绍了在android中自定义视图动画的方法,里面用了一个变换矩阵的方法来进行动画的处理,关于详细的内容,可以参考我的上一篇文章: [Android基础知识]打造自己的动画效果
通过这篇文章里介绍的变换矩阵,我们可以实现大多数的动画效果,不过这种方式,大多实现的是一种2D效果,如果向实现三维空间中的效果又什么方法呢?下面就为 ...
import android.content.C import android.util.AttributeS import android.view.KeyE import android.view.MotionE import android.widget.G public class DetialG ...
一.前言 转载请标明出处:http://blog.csdn.net/wlwlwlwl015/article/details/ 有阵子没更新博客了,主要是最近公司接了个P2P的金融借贷项目没人做,被拉去写服务端,所以迟迟没时间继续学习大安卓,想了想自己的安卓水平和公司的专业安卓璟博比起来依旧差距挺大,于是乎我要加把劲赶上才行,所以继续翻开李刚疯 ...

我要回帖

更多关于 getchild 的文章

 

随机推荐