I am trying to make the CoverFlow below appear like a Horizontal Gallery. The original file looks like this
There are three classes
the CoverFlow.class which extends a gallery
public class CoverFlow extends Gallery {
private Camera mCamera = new Camera();
private int mMaxRotationAngle = 50;
private int mMaxZoom = -380;
private int mCoveflowCenter;
private boolean mAlphaMode = true;
private boolean mCircleMode = false;
public CoverFlow(Context context) {
super(context);
this.setStaticTransformationsEnabled(true);
}
public CoverFlow(Context context, AttributeSet attrs) {
super(context, attrs);
this.setStaticTransformationsEnabled(true);
}
public CoverFlow(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.setStaticTransformationsEnabled(true);
}
public int getMaxRotationAngle() {
return mMaxRotationAngle;
}
public void setMaxRotationAngle(int maxRotationAngle) {
mMaxRotationAngle = maxRotationAngle;
}
public boolean getCircleMode() {
return mCircleMode;
}
public void setCircleMode(boolean isCircle) {
mCircleMode = isCircle;
}
public boolean getAlphaMode() {
return mAlphaMode;
}
public void setAlphaMode(boolean isAlpha) {
mAlphaMode = isAlpha;
}
public int getMaxZoom() {
return mMaxZoom;
}
public void setMaxZoom(int maxZoom) {
mMaxZoom = maxZoom;
}
private int getCenterOfCoverflow() {
return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2
+ getPaddingLeft();
}
private static int getCenterOfView(View view) {
return view.getLeft() + view.getWidth() / 2;
}
protected boolean getChildStaticTransformation(View child, Transformation t) {
final int childCenter = getCenterOfView(child);
final int childWidth = child.getWidth();
int rotationAngle = 0;
t.clear();
t.setTransformationType(Transformation.TYPE_MATRIX);
if (childCenter == mCoveflowCenter) {
transformImageBitmap((ImageView) child, t, 0);
} else {
rotationAngle = (int) (((float) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle);
if (Math.abs(rotationAngle) > mMaxRotationAngle) {
rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle
: mMaxRotationAngle;
}
transformImageBitmap((ImageView) child, t, rotationAngle);
}
return true;
}
/**
* This is called during layout when the size of this view has changed. If
* you were just added to the view hierarchy, you're called with the old
* values of 0.
*
* #param w
* Current width of this view.
* #param h
* Current height of this view.
* #param oldw
* Old width of this view.
* #param oldh
* Old height of this view.
*/
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
mCoveflowCenter = getCenterOfCoverflow();
super.onSizeChanged(w, h, oldw, oldh);
}
/**
* Transform the Image Bitmap by the Angle passed
*
* #param imageView
* ImageView the ImageView whose bitmap we want to rotate
* #param t
* transformation
* #param rotationAngle
* the Angle by which to rotate the Bitmap
*/
private void transformImageBitmap(ImageView child, Transformation t,
int rotationAngle) {
mCamera.save();
final Matrix imageMatrix = t.getMatrix();
final int imageHeight = child.getLayoutParams().height;
final int imageWidth = child.getLayoutParams().width;
final int rotation = Math.abs(rotationAngle);
mCamera.translate(0.0f, 0.0f, 100.0f);
// As the angle of the view gets less, zoom in
if (rotation <= mMaxRotationAngle) {
float zoomAmount = (float) (mMaxZoom + (rotation * 1.5));
mCamera.translate(0.0f, 0.0f, zoomAmount);
if (mCircleMode) {
if (rotation < 40)
mCamera.translate(0.0f, 155, 0.0f);
else
mCamera.translate(0.0f, (255 - rotation * 2.5f), 0.0f);
}
if (mAlphaMode) {
((ImageView) (child)).setAlpha((int) (255 - rotation * 2.5));
}
}
mCamera.rotateY(rotationAngle);
mCamera.getMatrix(imageMatrix);
imageMatrix.preTranslate(-(imageWidth ), -(imageHeight / 2));
imageMatrix.postTranslate((imageWidth ), (imageHeight / 2));
mCamera.restore();
}
}
The second class is my coverFlowActivity which is my class class
public class CoverFlowActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.main);
CoverFlow cf = new CoverFlow(this);
ImageAdapter ia = new ImageAdapter(this);
cf.setAdapter(ia);
cf.setAnimationDuration(1000);
setContentView(cf);
}
public class ImageAdapter extends BaseAdapter {
private int[] mImgs = {
R.drawable.img1,
R.drawable.img2,
R.drawable.img3,
R.drawable.img4,
R.drawable.img5,
R.drawable.img6,
R.drawable.img7,
R.drawable.img8
};
Context mContext;
public ImageAdapter(Context context) {
this.mContext = context;
}
#Override
public int getCount() {
return mImgs.length;
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return mImgs[position];
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ReflectionImage i = new ReflectionImage(mContext);
i.setImageResource(mImgs[position]);
i.setLayoutParams(new CoverFlow.LayoutParams(100, 100));
i.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
BitmapDrawable drawable = (BitmapDrawable) i.getDrawable();
drawable.setAntiAlias(true);
return i;
}
public float getScale(boolean focused, int offset) {
return Math.max(0, 1f/(float)Math.pow(2, Math.abs(offset)));
}
}
}
and the third activity is the reflected image below each image.
public class ReflectionImage extends ImageView {
//是否为Reflection模式
private boolean mReflectionMode = true;
public ReflectionImage(Context context) {
super(context);
}
public ReflectionImage(Context context, AttributeSet attrs) {
super(context, attrs);
//取得原始图片的bitmap并重画
Bitmap originalImage = ((BitmapDrawable)this.getDrawable()).getBitmap();
DoReflection(originalImage);
}
public ReflectionImage(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
Bitmap originalImage = ((BitmapDrawable)this.getDrawable()).getBitmap();
DoReflection(originalImage);
}
public void setReflectionMode(boolean isRef) {
mReflectionMode = isRef;
}
public boolean getReflectionMode() {
return mReflectionMode;
}
//偷懒了,只重写了setImageResource,和构造函数里面干了同样的事情
#Override
public void setImageResource(int resId) {
Bitmap originalImage = BitmapFactory.decodeResource(
getResources(), resId);
DoReflection(originalImage);
//super.setImageResource(resId);
}
private void DoReflection(Bitmap originalImage) {
final int reflectionGap = 4; //原始图片和反射图片中间的间距
int width = originalImage.getWidth();
int height = originalImage.getHeight();
//反转
Matrix matrix = new Matrix();
matrix.preScale(1, -1);
//reflectionImage就是下面透明的那部分,可以设置它的高度为原始的3/4,这样效果会更好些
Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0,
0, width, height, matrix, false);
//创建一个新的bitmap,高度为原来的两倍
Bitmap bitmapWithReflection = Bitmap.createBitmap(width, (height + height), Config.ARGB_8888);
Canvas canvasRef = new Canvas(bitmapWithReflection);
//先画原始的图片
canvasRef.drawBitmap(originalImage, 0, 0, null);
//画间距
Paint deafaultPaint = new Paint();
canvasRef.drawRect(0, height, width, height + reflectionGap, deafaultPaint);
//画被反转以后的图片
canvasRef.drawBitmap(reflectionImage, 0, height + reflectionGap, null);
// 创建一个渐变的蒙版放在下面被反转的图片上面
Paint paint = new Paint();
LinearGradient shader = new LinearGradient(0,
originalImage.getHeight(), 0, bitmapWithReflection.getHeight()
+ reflectionGap, 0x80ffffff, 0x00ffffff, TileMode.CLAMP);
// Set the paint to use this shader (linear gradient)
paint.setShader(shader);
// Set the Transfer mode to be porter duff and destination in
paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
// Draw a rectangle using the paint with our linear gradient
canvasRef.drawRect(0, height, width, bitmapWithReflection.getHeight()
+ reflectionGap, paint);
//调用ImageView中的setImageBitmap
this.setImageBitmap(bitmapWithReflection);
}
}
I want to make it appears like a gallery that is all images must have four dp margin and appear like the center image without any effects. Can someone please help me to achieve this.
Please try this:
private int mMaxRotationAngle = 0;
and
CoverFlow cf = new CoverFlow(this);
cf.setSpacing(-30);
in the CoverFlowActivity
From what I understood, you need a ViewPager:
http://developer.android.com/reference/android/support/v4/view/ViewPager.html
NOTE: add the support library to support API till level 4 ;-)
Some usefull code: http://commonsware.com/blog/2012/08/20/multiple-view-viewpager-options.html
setContentView(R.layout.main);
mContainer = (PagerContainer) findViewById(R.id.pager_container);
ViewPager pager = mContainer.getViewPager();
PagerAdapter adapter = new MyPagerAdapter();
pager.setAdapter(adapter);
//Necessary or the pager will only have one extra page to show
// make this at least however many pages you can see
pager.setOffscreenPageLimit(adapter.getCount());
//A little space between pages
pager.setPageMargin(15);
//If hardware acceleration is enabled, you should also remove
// clipping on the pager for its children.
pager.setClipChildren(false);
Adding padding and margin should be trivial ;-)
Related
In one of my apps I have created a circular view with multiple colors,In which I want to set click listener on each color arch
Below is the image and code for drawing that view
Custom view class code
public class CircularStatusView extends View {
private static final float DEFAULT_PORTION_WIDTH = 10;
private static final int DEFAULT_PORTION_SPACING = 5;
private static final int DEFAULT_COLOR = Color.parseColor("#D81B60");
private static final float DEFAULT_PORTIONS_COUNT = 1;
private static final float START_DEGREE =-90;
private float radius;
private float portionWidth = DEFAULT_PORTION_WIDTH;
private int portionSpacing = DEFAULT_PORTION_SPACING;
private int portionColor = DEFAULT_COLOR;
private float portionsCount = DEFAULT_PORTIONS_COUNT;
private RectF mBorderRect = new RectF();
private Paint paint;
private SparseIntArray portionToUpdateMap = new SparseIntArray();
private Context context;
public CircularStatusView(Context context) {
super(context);
init(context, null, -1);
}
private void init(Context context, AttributeSet attrs, int defStyle) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircularStatusView, defStyle, 0);
if (a != null) {
portionColor = a.getColor(R.styleable.CircularStatusView_portion_color, DEFAULT_COLOR);
portionWidth = a.getDimensionPixelSize(R.styleable.CircularStatusView_portion_width, (int) DEFAULT_PORTION_WIDTH);
portionSpacing = a.getDimensionPixelSize(R.styleable.CircularStatusView_portion_spacing, DEFAULT_PORTION_SPACING);
portionsCount = a.getInteger(R.styleable.CircularStatusView_portions_count, (int) DEFAULT_PORTIONS_COUNT);
a.recycle();
}
paint = getPaint();
}
public CircularStatusView(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
init(context, attrs, -1);
}
public CircularStatusView(Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBorderRect.set(calculateBounds());
radius = Math.min((mBorderRect.height() - portionWidth) / 2.0f, (mBorderRect.width() - portionWidth) / 2.0f);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float radius = this.radius;
float center_x = mBorderRect.centerX();
float center_y = mBorderRect.centerY();
final RectF oval = getOval(radius, center_x, center_y);
float degree = 360 / portionsCount;
float percent = 100 / portionsCount;
for (int i = 0; i < portionsCount; i++) {
paint.setColor(getPaintColorForIndex(i));
float startAngle = START_DEGREE + (degree * i);
canvas.drawArc(oval, (getSpacing() / 2) + startAngle, getProgressAngle(percent) - getSpacing(), false, paint);
}
}
private int getPaintColorForIndex(int i) {
if (portionToUpdateMap.indexOfKey(i) >= 0) { //if key is exists
return portionToUpdateMap.get(i);
} else {
return portionColor;
}
}
#NonNull
private RectF getOval(float radius, float center_x, float center_y) {
final RectF oval = new RectF();
oval.set(center_x - radius,
center_y - radius,
center_x + radius,
center_y + radius);
return oval;
}
#NonNull
private Paint getPaint() {
Paint paint = new Paint();
paint.setColor(portionColor);
paint.setStyle(Paint.Style.STROKE);
paint.setAntiAlias(true);
paint.setStrokeWidth(portionWidth);
paint.setStrokeCap(Paint.Cap.BUTT);
return paint;
}
private int getSpacing() {
return portionsCount == 1 ? 0 : portionSpacing;
}
private RectF calculateBounds() {
int availableWidth = getWidth() - getPaddingLeft() - getPaddingRight();
int availableHeight = getHeight() - getPaddingTop() - getPaddingBottom();
int sideLength = Math.min(availableWidth, availableHeight);
float left = getPaddingLeft() + (availableWidth - sideLength) / 2f;
float top = getPaddingTop() + (availableHeight - sideLength) / 2f;
return new RectF(left, top, left + sideLength, top + sideLength);
}
private float getProgressAngle(float percent) {
return percent / (float) 100 * 360;
}
public void setPortionsCount(int portionsCount) {
this.portionsCount = (float) portionsCount;
}
public void setPortionSpacing(int spacing) {
portionSpacing = spacing;
}
public void setPortionWidth(float portionWidth) {
this.portionWidth = portionWidth;
}
public void setCustomPaint(Paint paint) {
this.paint = paint;
}
public void setPortionsColor(int color) {
this.portionColor = color;
portionToUpdateMap.clear();
invalidate();
}
public void setPortionColorForIndex(int index, int color) {
if (index > portionsCount - 1) {
throw new IllegalArgumentException("Index is Bigger than the count!");
} else {
Log.d("3llomi", "adding index to map " + index);
portionToUpdateMap.put(index, color);
invalidate();
}
}
}
and in my activity class
CircularStatusView circularStatusView = findViewById(R.id.circular_status_view);
circularStatusView.setPortionsCount(6);
for (int i=0; i<AppConstants.outerCircleColors.length; i++){
circularStatusView.setPortionColorForIndex(i,Color.parseColor(AppConstants.outerCircleColors[i]));
How I can set click listener on each color arch in this view? Can someone help me out in this?
You can get the pixel from the CircularStatusView, By using OnTouchListener:
CircularStatusView view = ((CircularStatusView)v);
Bitmap bitmap = ((BitmapDrawable)view.getDrawable()).getBitmap();
int pixel = bitmap.getPixel(x,y);
You can just compare the pixel to a different color. Like...
if(pixel == Color.RED){
//It's Red Color
}
You can create an interface listener for onTouch events. Check the onTouch co-ordinates. Depending on their position you can send back the touched part index to the interface listener.
Dummy code:
public class CircularStatusView extends View {
private StatusViewTouchListener listener;
...
..
.
public void setOnClickListener(StatusViewTouchListener listener) {
this.listener = listener;
}
public interface StatusViewTouchListener {
public void onStatusViewTouch(int index);
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
int indexOfTouchedColor;
// Check the touch points and determine in which color part it exists.
listener.onStatusViewTouch(indexOfTouchedColor);
return true;
}
}
Implement the listener where where you are using the view and set it to the View.
public class yourActivity extends Activity implements StatusViewTouchListener {
...
..
.
CircularStatusView circularStatusView = findViewById(R.id.circular_status_view);
circularStatusView.setPortionsCount(6);
for (int i=0; i<AppConstants.outerCircleColors.length; i++){
circularStatusView.setPortionColorForIndex(i,Color.parseColor(AppConstants.outerCircleColors[i]));
circularStatusView.setOnClickListener(this);
...
..
#Override
public void onStatusViewTouch(int index) {
// Perform your action based on the index of the color
}
}
I'm using a custom view to get ripple effect for the pre-lollipop devices. But I also need to customize the container shape like a curved shape.I want to be the button like this.
As you can see in the second and third buttons when we tap the view the ripple effect animation goes outside of the container view. So how to resolve this?
Please note that I want this ripple effect for the Kitkat version with the ability to change the ripple color. So is this possible?
Here is my custom view which is used for the ripple effect
public class MyRippleView extends FrameLayout {
private int WIDTH;
private int HEIGHT;
private int frameRate = 10;
private int rippleDuration = 400;
private int rippleAlpha = 90;
private Handler canvasHandler;
private float radiusMax = 0;
private boolean animationRunning = false;
private int timer = 0;
private int timerEmpty = 0;
private int durationEmpty = -1;
private float x = -1;
private float y = -1;
private int zoomDuration;
private float zoomScale;
private ScaleAnimation scaleAnimation;
private Boolean hasToZoom;
private Boolean isCentered;
private Integer rippleType;
private Paint paint;
private Bitmap originBitmap;
private int rippleColor;
private int ripplePadding;
private GestureDetector gestureDetector;
private final Runnable runnable = new Runnable() {
#Override
public void run() {
invalidate();
}
};
private OnRippleCompleteListener onCompletionListener;
public MyRippleView(Context context) {
super(context);
}
public MyRippleView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public MyRippleView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs);
}
/**
* Method that initializes all fields and sets listeners
*
* #param context Context used to create this view
* #param attrs Attribute used to initialize fields
*/
private void init(final Context context, final AttributeSet attrs) {
if (isInEditMode())
return;
final TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RippleView);
rippleColor = typedArray.getColor(R.styleable.RippleView_rv_color, getResources().getColor(R.color.rippelColor));
rippleType = typedArray.getInt(R.styleable.RippleView_rv_type, 0);
hasToZoom = typedArray.getBoolean(R.styleable.RippleView_rv_zoom, false);
isCentered = typedArray.getBoolean(R.styleable.RippleView_rv_centered, false);
rippleDuration = typedArray.getInteger(R.styleable.RippleView_rv_rippleDuration, rippleDuration);
frameRate = typedArray.getInteger(R.styleable.RippleView_rv_framerate, frameRate);
rippleAlpha = typedArray.getInteger(R.styleable.RippleView_rv_alpha, rippleAlpha);
ripplePadding = typedArray.getDimensionPixelSize(R.styleable.RippleView_rv_ripplePadding, 0);
canvasHandler = new Handler();
zoomScale = typedArray.getFloat(R.styleable.RippleView_rv_zoomScale, 1.03f);
zoomDuration = typedArray.getInt(R.styleable.RippleView_rv_zoomDuration, 200);
typedArray.recycle();
paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL);
paint.setColor(rippleColor);
paint.setAlpha(rippleAlpha);
this.setWillNotDraw(false);
gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
#Override
public void onLongPress(MotionEvent event) {
super.onLongPress(event);
animateRipple(event);
sendClickEvent(true);
}
#Override
public boolean onSingleTapConfirmed(MotionEvent e) {
return true;
}
#Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
});
this.setDrawingCacheEnabled(true);
this.setClickable(true);
}
#Override
public void draw(Canvas canvas) {
super.draw(canvas);
if (animationRunning) {
if (rippleDuration <= timer * frameRate) {
animationRunning = false;
timer = 0;
durationEmpty = -1;
timerEmpty = 0;
canvas.restore();
invalidate();
if (onCompletionListener != null) onCompletionListener.onComplete(this);
return;
} else
canvasHandler.postDelayed(runnable, frameRate);
if (timer == 0)
canvas.save();
canvas.drawCircle(x, y, (radiusMax * (((float) timer * frameRate) / rippleDuration)), paint);
paint.setColor(Color.parseColor("#ffff4444"));
if (rippleType == 1 && originBitmap != null && (((float) timer * frameRate) / rippleDuration) > 0.4f) {
if (durationEmpty == -1)
durationEmpty = rippleDuration - timer * frameRate;
timerEmpty++;
final Bitmap tmpBitmap = getCircleBitmap((int) ((radiusMax) * (((float) timerEmpty * frameRate) / (durationEmpty))));
canvas.drawBitmap(tmpBitmap, 0, 0, paint);
tmpBitmap.recycle();
}
paint.setColor(rippleColor);
if (rippleType == 1) {
if ((((float) timer * frameRate) / rippleDuration) > 0.6f)
paint.setAlpha((int) (rippleAlpha - ((rippleAlpha) * (((float) timerEmpty * frameRate) / (durationEmpty)))));
else
paint.setAlpha(rippleAlpha);
}
else
paint.setAlpha((int) (rippleAlpha - ((rippleAlpha) * (((float) timer * frameRate) / rippleDuration))));
timer++;
}
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
WIDTH = w;
HEIGHT = h;
scaleAnimation = new ScaleAnimation(1.0f, zoomScale, 1.0f, zoomScale, w / 2, h / 2);
scaleAnimation.setDuration(zoomDuration);
scaleAnimation.setRepeatMode(Animation.REVERSE);
scaleAnimation.setRepeatCount(1);
}
/**
* Launch Ripple animation for the current view with a MotionEvent
*
* #param event MotionEvent registered by the Ripple gesture listener
*/
public void animateRipple(MotionEvent event) {
createAnimation(event.getX(), event.getY());
}
/**
* Launch Ripple animation for the current view centered at x and y position
*
* #param x Horizontal position of the ripple center
* #param y Vertical position of the ripple center
*/
public void animateRipple(final float x, final float y) {
createAnimation(x, y);
}
/**
* Create Ripple animation centered at x, y
*
* #param x Horizontal position of the ripple center
* #param y Vertical position of the ripple center
*/
private void createAnimation(final float x, final float y) {
if (this.isEnabled() && !animationRunning) {
if (hasToZoom)
this.startAnimation(scaleAnimation);
radiusMax = Math.max(WIDTH, HEIGHT);
if (rippleType != 2)
radiusMax /= 2;
radiusMax -= ripplePadding;
if (isCentered || rippleType == 1) {
this.x = getMeasuredWidth() / 2;
this.y = getMeasuredHeight() / 2;
} else {
this.x = x;
this.y = y;
}
animationRunning = true;
if (rippleType == 1 && originBitmap == null)
originBitmap = getDrawingCache(true);
invalidate();
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (gestureDetector.onTouchEvent(event)) {
animateRipple(event);
sendClickEvent(false);
}
return super.onTouchEvent(event);
}
#Override
public boolean onInterceptTouchEvent(MotionEvent event) {
this.onTouchEvent(event);
return super.onInterceptTouchEvent(event);
}
/**
* Send a click event if parent view is a Listview instance
*
* #param isLongClick Is the event a long click ?
*/
private void sendClickEvent(final Boolean isLongClick) {
if (getParent() instanceof AdapterView) {
final AdapterView adapterView = (AdapterView) getParent();
final int position = adapterView.getPositionForView(this);
final long id = adapterView.getItemIdAtPosition(position);
if (isLongClick) {
if (adapterView.getOnItemLongClickListener() != null)
adapterView.getOnItemLongClickListener().onItemLongClick(adapterView, this, position, id);
} else {
if (adapterView.getOnItemClickListener() != null)
adapterView.getOnItemClickListener().onItemClick(adapterView, this, position, id);
}
}
}
private Bitmap getCircleBitmap(final int radius) {
final Bitmap output = Bitmap.createBitmap(originBitmap.getWidth(), originBitmap.getHeight(), Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(output);
final Paint paint = new Paint();
final Rect rect = new Rect((int)(x - radius), (int)(y - radius), (int)(x + radius), (int)(y + radius));
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
canvas.drawCircle(x, y, radius, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(originBitmap, rect, rect, paint);
return output;
}
/**
* Set Ripple color, default is #FFFFFF
*
* #param rippleColor New color resource
*/
#ColorRes
public void setRippleColor(int rippleColor) {
this.rippleColor = getResources().getColor(rippleColor);
}
public int getRippleColor() {
return rippleColor;
}
public RippleType getRippleType()
{
return RippleType.values()[rippleType];
}
/**
* Set Ripple type, default is RippleType.SIMPLE
*
* #param rippleType New Ripple type for next animation
*/
public void setRippleType(final RippleType rippleType)
{
this.rippleType = rippleType.ordinal();
}
public Boolean isCentered()
{
return isCentered;
}
/**
* Set if ripple animation has to be centered in its parent view or not, default is False
*
* #param isCentered
*/
public void setCentered(final Boolean isCentered)
{
this.isCentered = isCentered;
}
public int getRipplePadding()
{
return ripplePadding;
}
/**
* Set Ripple padding if you want to avoid some graphic glitch
*
* #param ripplePadding New Ripple padding in pixel, default is 0px
*/
public void setRipplePadding(int ripplePadding)
{
this.ripplePadding = ripplePadding;
}
public Boolean isZooming()
{
return hasToZoom;
}
/**
* At the end of Ripple effect, the child views has to zoom
*
* #param hasToZoom Do the child views have to zoom ? default is False
*/
public void setZooming(Boolean hasToZoom)
{
this.hasToZoom = hasToZoom;
}
public float getZoomScale()
{
return zoomScale;
}
/**
* Scale of the end animation
*
* #param zoomScale Value of scale animation, default is 1.03f
*/
public void setZoomScale(float zoomScale)
{
this.zoomScale = zoomScale;
}
public int getZoomDuration()
{
return zoomDuration;
}
/**
* Duration of the ending animation in ms
*
* #param zoomDuration Duration, default is 200ms
*/
public void setZoomDuration(int zoomDuration)
{
this.zoomDuration = zoomDuration;
}
public int getRippleDuration()
{
return rippleDuration;
}
/**
* Duration of the Ripple animation in ms
*
* #param rippleDuration Duration, default is 400ms
*/
public void setRippleDuration(int rippleDuration)
{
this.rippleDuration = rippleDuration;
}
public int getFrameRate()
{
return frameRate;
}
/**
* Set framerate for Ripple animation
*
* #param frameRate New framerate value, default is 10
*/
public void setFrameRate(int frameRate)
{
this.frameRate = frameRate;
}
public int getRippleAlpha()
{
return rippleAlpha;
}
/**
* Set alpha for ripple effect color
*
* #param rippleAlpha Alpha value between 0 and 255, default is 90
*/
public void setRippleAlpha(int rippleAlpha)
{
this.rippleAlpha = rippleAlpha;
}
public void setOnRippleCompleteListener(OnRippleCompleteListener listener) {
this.onCompletionListener = listener;
}
/**
* Defines a callback called at the end of the Ripple effect
*/
public interface OnRippleCompleteListener {
void onComplete(MyRippleView rippleView);
}
public enum RippleType {
SIMPLE(0),
DOUBLE(1),
RECTANGLE(2);
int type;
RippleType(int type)
{
this.type = type;
}
}
}
In the layout XML file
<FrameLayout
android:background="#drawable/curved_button"
android:layout_width="match_parent"
android:layout_height="50dp">
<com.package.MyRippleView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:rv_color="#color/colorAccent"
rv_centered="true">
</com.package.MyRippleView>
</FrameLayout>
Curved Shape
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item >
<shape android:shape="rectangle" >
<corners android:radius="40dip" />
<stroke android:width="1dp" android:color="#FF9A00" />
</shape>
</item>
It's possible. The easiest way is to use Carbon which does such things just like that. I was able to recreate your button using only xml and run it on Gingerbread.
<carbon.widget.Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Rounded with ripple"
android:textColor="#color/carbon_amber_700"
app:carbon_cornerRadius="100dp"
app:carbon_backgroundTint="#color/carbon_white"
app:carbon_rippleColor="#40ff0000"
app:carbon_stroke="#color/carbon_amber_700"
app:carbon_strokeWidth="2dp" />
The downside is that Carbon is huge and you may not want to include it just for that one button.
If you wish to do that by yourself, you should use a path and a PorterDuff mode to clip your button to a rounded rect.
private float cornerRadius;
private Path cornersMask;
private static PorterDuffXfermode pdMode = new PorterDuffXfermode(PorterDuff.Mode.CLEAR);
private void initCorners() {
cornersMask = new Path();
cornersMask.addRoundRect(new RectF(0, 0, getWidth(), getHeight()), cornerRadius, cornerRadius, Path.Direction.CW);
cornersMask.setFillType(Path.FillType.INVERSE_WINDING);
}
#Override
public void draw(#NonNull Canvas canvas) {
int saveCount = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.ALL_SAVE_FLAG);
super.draw(canvas);
paint.setXfermode(pdMode);
canvas.drawPath(cornersMask, paint);
canvas.restoreToCount(saveCount);
paint.setXfermode(null);
}
And you should probably use ViewOutlineProvider on Lollipop to use native stuff where possible.
I want to create RoundedImageView for some ImageView used in my app. I am creating custom view for that.
Below is the Xml file and source code for custom ImageView.
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/deleteCallLog"
android:orientation="horizontal" >
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_margin="4dip" >
<com.nimbuzz.ui.RoundedImageView
android:id="#+id/avatarImage"
android:layout_width="48dip"
android:layout_height="48dip"
android:layout_centerHorizontal="true"
android:src="#drawable/default_avatar" />
<ImageView
android:id="#+id/subCallTypeIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#id/avatarImage"
android:layout_alignRight="#id/avatarImage"
android:visibility="gone" />
</RelativeLayout>
</LinearLayout>
Line: Bitmap bitmap = b.copy(Config.ARGB_8888, true); causing NullPointerException.
It does'nt always happens . On some screens this code works.
RoundedImageView.java:
public class RoundedImageView extends ImageView {
public RoundedImageView(Context context) {
super(context);
}
public RoundedImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RoundedImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onDraw(Canvas canvas)
{
Drawable drawable = getDrawable();
if (drawable == null) {
return;
}
if (getWidth() == 0 || getHeight() == 0) {
return;
}
Bitmap b = ((BitmapDrawable)drawable).getBitmap();
Bitmap bitmap = b.copy(Config.ARGB_8888, true);
int w = getWidth(), h = getHeight();
Bitmap roundBitmap = getCroppedBitmap(b, w);
canvas.drawBitmap(roundBitmap, 0, 0, null);
}
public static Bitmap getCroppedBitmap(Bitmap bmp, int radius) {
Bitmap sbmp;
if (bmp.getWidth() != radius || bmp.getHeight() != radius) {
float smallest = Math.min(bmp.getWidth(), bmp.getHeight());
float factor = smallest / radius;
sbmp = Bitmap.createScaledBitmap(bmp, (int)(bmp.getWidth() / factor), (int)(bmp.getHeight() / factor), false);
} else {
sbmp = bmp;
}
Bitmap output = Bitmap.createBitmap(radius, radius,
Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xffa19774;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, radius, radius);
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(Color.parseColor("#BAB399"));
canvas.drawCircle(radius / 2 + 0.7f,
radius / 2 + 0.7f, radius / 2 + 0.1f, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(sbmp, rect, rect, paint);
return output;
}
}
Try this o create own Imageview and directly set the bitmap or resource in imageview..
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.widget.ImageView;
#SuppressLint("DrawAllocation")
public class RoundedCornerImageView extends ImageView {
public RoundedCornerImageView(Context context) {
super(context);
}
public RoundedCornerImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RoundedCornerImageView(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onDraw(Canvas canvas) {
float radius = 90.0f; // angle of round corners
Path clipPath = new Path();
RectF rect = new RectF(0, 0, this.getWidth(), this.getHeight());
clipPath.addRoundRect(rect, radius, radius, Path.Direction.CW);
canvas.clipPath(clipPath);
super.onDraw(canvas);
}
}
Custom CirularImageView
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.ImageView;
/**
* Custom ImageView for circular images in Android while maintaining the
* best draw performance and supporting custom borders & selectors.
*/
public class CircularImageView extends ImageView {
// For logging purposes
private static final String TAG = CircularImageView.class.getSimpleName();
// Default property values
private static final boolean SHADOW_ENABLED = false;
private static final float SHADOW_RADIUS = 4f;
private static final float SHADOW_DX = 0f;
private static final float SHADOW_DY = 2f;
private static final int SHADOW_COLOR = Color.BLACK;
// Border & Selector configuration variables
private boolean hasBorder;
private boolean hasSelector;
private boolean isSelected;
private int borderWidth;
private int canvasSize;
private int selectorStrokeWidth;
// Shadow properties
private boolean shadowEnabled;
private float shadowRadius;
private float shadowDx;
private float shadowDy;
private int shadowColor;
// Objects used for the actual drawing
private BitmapShader shader;
private Bitmap image;
private Paint paint;
private Paint paintBorder;
private Paint paintSelectorBorder;
private ColorFilter selectorFilter;
public CircularImageView(Context context) {
this(context, null, R.styleable.CircularImageViewStyle_circularImageViewDefault);
}
public CircularImageView(Context context, AttributeSet attrs) {
this(context, attrs, R.styleable.CircularImageViewStyle_circularImageViewDefault);
}
public CircularImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public CircularImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context, attrs, defStyleAttr);
}
/**
* Initializes paint objects and sets desired attributes.
* #param context Context
* #param attrs Attributes
* #param defStyle Default Style
*/
private void init(Context context, AttributeSet attrs, int defStyle) {
// Initialize paint objects
paint = new Paint();
paint.setAntiAlias(true);
paintBorder = new Paint();
paintBorder.setAntiAlias(true);
paintBorder.setStyle(Paint.Style.STROKE);
paintSelectorBorder = new Paint();
paintSelectorBorder.setAntiAlias(true);
// Enable software rendering on HoneyComb and up. (needed for shadow)
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
setLayerType(LAYER_TYPE_SOFTWARE, null);
// Load the styled attributes and set their properties
TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.CircularImageView, defStyle, 0);
// Check for extra features being enabled
hasBorder = attributes.getBoolean(R.styleable.CircularImageView_civ_border, false);
hasSelector = attributes.getBoolean(R.styleable.CircularImageView_civ_selector, false);
shadowEnabled = attributes.getBoolean(R.styleable.CircularImageView_civ_shadow, SHADOW_ENABLED);
// Set border properties, if enabled
if(hasBorder) {
int defaultBorderSize = (int) (2 * context.getResources().getDisplayMetrics().density + 0.5f);
setBorderWidth(attributes.getDimensionPixelOffset(R.styleable.CircularImageView_civ_borderWidth, defaultBorderSize));
setBorderColor(attributes.getColor(R.styleable.CircularImageView_civ_borderColor, Color.WHITE));
}
// Set selector properties, if enabled
if(hasSelector) {
int defaultSelectorSize = (int) (2 * context.getResources().getDisplayMetrics().density + 0.5f);
setSelectorColor(attributes.getColor(R.styleable.CircularImageView_civ_selectorColor, Color.TRANSPARENT));
setSelectorStrokeWidth(attributes.getDimensionPixelOffset(R.styleable.CircularImageView_civ_selectorStrokeWidth, defaultSelectorSize));
setSelectorStrokeColor(attributes.getColor(R.styleable.CircularImageView_civ_selectorStrokeColor, Color.BLUE));
}
// Set shadow properties, if enabled
if(shadowEnabled) {
shadowRadius = attributes.getFloat(R.styleable.CircularImageView_civ_shadowRadius, SHADOW_RADIUS);
shadowDx = attributes.getFloat(R.styleable.CircularImageView_civ_shadowDx, SHADOW_DX);
shadowDy = attributes.getFloat(R.styleable.CircularImageView_civ_shadowDy, SHADOW_DY);
shadowColor = attributes.getColor(R.styleable.CircularImageView_civ_shadowColor, SHADOW_COLOR);
setShadowEnabled(true);
}
// We no longer need our attributes TypedArray, give it back to cache
attributes.recycle();
}
/**
* Sets the CircularImageView's border width in pixels.
* #param borderWidth Width in pixels for the border.
*/
public void setBorderWidth(int borderWidth) {
this.borderWidth = borderWidth;
if(paintBorder != null)
paintBorder.setStrokeWidth(borderWidth);
requestLayout();
invalidate();
}
/**
* Sets the CircularImageView's basic border color.
* #param borderColor The new color (including alpha) to set the border.
*/
public void setBorderColor(int borderColor) {
if (paintBorder != null)
paintBorder.setColor(borderColor);
this.invalidate();
}
/**
* Sets the color of the selector to be draw over the
* CircularImageView. Be sure to provide some opacity.
* #param selectorColor The color (including alpha) to set for the selector overlay.
*/
public void setSelectorColor(int selectorColor) {
this.selectorFilter = new PorterDuffColorFilter(selectorColor, PorterDuff.Mode.SRC_ATOP);
this.invalidate();
}
/**
* Sets the stroke width to be drawn around the CircularImageView
* during click events when the selector is enabled.
* #param selectorStrokeWidth Width in pixels for the selector stroke.
*/
public void setSelectorStrokeWidth(int selectorStrokeWidth) {
this.selectorStrokeWidth = selectorStrokeWidth;
this.requestLayout();
this.invalidate();
}
/**
* Sets the stroke color to be drawn around the CircularImageView
* during click events when the selector is enabled.
* #param selectorStrokeColor The color (including alpha) to set for the selector stroke.
*/
public void setSelectorStrokeColor(int selectorStrokeColor) {
if (paintSelectorBorder != null)
paintSelectorBorder.setColor(selectorStrokeColor);
this.invalidate();
}
/**
* Enables a dark shadow for this CircularImageView.
* #param enabled Set to true to draw a shadow or false to disable it.
*/
public void setShadowEnabled(boolean enabled) {
shadowEnabled = enabled;
updateShadow();
}
/**
* Enables a dark shadow for this CircularImageView.
* If the radius is set to 0, the shadow is removed.
* #param radius Radius for the shadow to extend to.
* #param dx Horizontal shadow offset.
* #param dy Vertical shadow offset.
* #param color The color of the shadow to apply.
*/
public void setShadow(float radius, float dx, float dy, int color) {
shadowRadius = radius;
shadowDx = dx;
shadowDy = dy;
shadowColor = color;
updateShadow();
}
#Override
public void onDraw(Canvas canvas) {
// Don't draw anything without an image
if(image == null)
return;
// Nothing to draw (Empty bounds)
if(image.getHeight() == 0 || image.getWidth() == 0)
return;
// Update shader if canvas size has changed
int oldCanvasSize = canvasSize;
canvasSize = getWidth() < getHeight() ? getWidth() : getHeight();
if(oldCanvasSize != canvasSize)
updateBitmapShader();
// Apply shader to paint
paint.setShader(shader);
// Keep track of selectorStroke/border width
int outerWidth = 0;
// Get the exact X/Y axis of the view
int center = canvasSize / 2;
if(hasSelector && isSelected) { // Draw the selector stroke & apply the selector filter, if applicable
outerWidth = selectorStrokeWidth;
center = (canvasSize - (outerWidth * 2)) / 2;
paint.setColorFilter(selectorFilter);
canvas.drawCircle(center + outerWidth, center + outerWidth, ((canvasSize - (outerWidth * 2)) / 2) + outerWidth - 4.0f, paintSelectorBorder);
}
else if(hasBorder) { // If no selector was drawn, draw a border and clear the filter instead... if enabled
outerWidth = borderWidth;
center = (canvasSize - (outerWidth * 2)) / 2;
paint.setColorFilter(null);
RectF rekt = new RectF(0 + outerWidth / 2, 0 + outerWidth / 2, canvasSize - outerWidth / 2, canvasSize - outerWidth / 2);
canvas.drawArc(rekt, 360, 360, false, paintBorder);
//canvas.drawCircle(center + outerWidth, center + outerWidth, ((canvasSize - (outerWidth * 2)) / 2) + outerWidth - 4.0f, paintBorder);
}
else // Clear the color filter if no selector nor border were drawn
paint.setColorFilter(null);
// Draw the circular image itself
canvas.drawCircle(center + outerWidth, center + outerWidth, ((canvasSize - (outerWidth * 2)) / 2), paint);
}
#Override
public boolean dispatchTouchEvent(MotionEvent event) {
// Check for clickable state and do nothing if disabled
if(!this.isClickable()) {
this.isSelected = false;
return super.onTouchEvent(event);
}
// Set selected state based on Motion Event
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
this.isSelected = true;
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_SCROLL:
case MotionEvent.ACTION_OUTSIDE:
case MotionEvent.ACTION_CANCEL:
this.isSelected = false;
break;
}
// Redraw image and return super type
this.invalidate();
return super.dispatchTouchEvent(event);
}
#Override
public void setImageURI(Uri uri) {
super.setImageURI(uri);
// Extract a Bitmap out of the drawable & set it as the main shader
image = drawableToBitmap(getDrawable());
if(canvasSize > 0)
updateBitmapShader();
}
#Override
public void setImageResource(int resId) {
super.setImageResource(resId);
// Extract a Bitmap out of the drawable & set it as the main shader
image = drawableToBitmap(getDrawable());
if(canvasSize > 0)
updateBitmapShader();
}
#Override
public void setImageDrawable(Drawable drawable) {
super.setImageDrawable(drawable);
// Extract a Bitmap out of the drawable & set it as the main shader
image = drawableToBitmap(getDrawable());
if(canvasSize > 0)
updateBitmapShader();
}
#Override
public void setImageBitmap(Bitmap bm) {
super.setImageBitmap(bm);
// Extract a Bitmap out of the drawable & set it as the main shader
image = bm;
if(canvasSize > 0)
updateBitmapShader();
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = measureWidth(widthMeasureSpec);
int height = measureHeight(heightMeasureSpec);
setMeasuredDimension(width, height);
}
private int measureWidth(int measureSpec) {
int result;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
// The parent has determined an exact size for the child.
result = specSize;
}
else if (specMode == MeasureSpec.AT_MOST) {
// The child can be as large as it wants up to the specified size.
result = specSize;
}
else {
// The parent has not imposed any constraint on the child.
result = canvasSize;
}
return result;
}
private int measureHeight(int measureSpecHeight) {
int result;
int specMode = MeasureSpec.getMode(measureSpecHeight);
int specSize = MeasureSpec.getSize(measureSpecHeight);
if (specMode == MeasureSpec.EXACTLY) {
// We were told how big to be
result = specSize;
} else if (specMode == MeasureSpec.AT_MOST) {
// The child can be as large as it wants up to the specified size.
result = specSize;
} else {
// Measure the text (beware: ascent is a negative number)
result = canvasSize;
}
return (result + 2);
}
// TODO: Update shadow layers based on border/selector state and visibility.
private void updateShadow() {
float radius = shadowEnabled ? shadowRadius : 0;
//paint.setShadowLayer(radius, shadowDx, shadowDy, shadowColor);
paintBorder.setShadowLayer(radius, shadowDx, shadowDy, shadowColor);
paintSelectorBorder.setShadowLayer(radius, shadowDx, shadowDy, shadowColor);
}
/**
* Convert a drawable object into a Bitmap.
* #param drawable Drawable to extract a Bitmap from.
* #return A Bitmap created from the drawable parameter.
*/
public Bitmap drawableToBitmap(Drawable drawable) {
if (drawable == null) // Don't do anything without a proper drawable
return null;
else if (drawable instanceof BitmapDrawable) { // Use the getBitmap() method instead if BitmapDrawable
Log.i(TAG, "Bitmap drawable!");
return ((BitmapDrawable) drawable).getBitmap();
}
int intrinsicWidth = drawable.getIntrinsicWidth();
int intrinsicHeight = drawable.getIntrinsicHeight();
if (!(intrinsicWidth > 0 && intrinsicHeight > 0))
return null;
try {
// Create Bitmap object out of the drawable
Bitmap bitmap = Bitmap.createBitmap(intrinsicWidth, intrinsicHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
} catch (OutOfMemoryError e) {
// Simply return null of failed bitmap creations
Log.e(TAG, "Encountered OutOfMemoryError while generating bitmap!");
return null;
}
}
// TODO TEST REMOVE
public void setIconModeEnabled(boolean e) {}
/**
* Re-initializes the shader texture used to fill in
* the Circle upon drawing.
*/
public void updateBitmapShader() {
if (image == null)
return;
shader = new BitmapShader(image, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
if(canvasSize != image.getWidth() || canvasSize != image.getHeight()) {
Matrix matrix = new Matrix();
float scale = (float) canvasSize / (float) image.getWidth();
matrix.setScale(scale, scale);
shader.setLocalMatrix(matrix);
}
}
/**
* #return Whether or not this view is currently
* in its selected state.
*/
public boolean isSelected() {
return this.isSelected;
}
}
Usage
<com.yourpackage.CircularImageView
android:layout_width="100dp"
android:id="#+id/btn_myprofile"
android:layout_height="100dp"
app:civ_border="true"
app:civ_borderColor="#FF9900"
app:civ_borderWidth="2dp"
app:civ_shadow="false"
android:background="#drawable/profile_icon" />
https://github.com/hdodenhof/CircleImageView
https://github.com/lopspower/CircularImageView
I have IndicationBar class that should draw rectangle with logo inside and on int value case change rectangle color. I am new to java and android so im learning everyday.
At this moment the value of int is changing in other class and i call it BluetoothChat.statusSviesos. its public static int. Do i need to create interface Listener or how can i run private void Sviesos() every time int is changed? It runs only once in start.
public class IndicationBar extends View {
private static final String TAG = IndicationBar.class.getSimpleName();
// drawing tools
private RectF Rect;
private Paint rectPaint;
private Paint rimCirclePaint;
private RectF faceRect;
private Bitmap faceTexture;
private Paint facePaint;
private Paint rimShadowPaint;
private Paint titlePaint;
private Path titlePath;
private Paint logoPaint;
private Bitmap logo;
private Matrix logoMatrix;
private float logoScale;
private Paint backgroundPaint;
// end drawing tools
private Bitmap background; // holds the cached static part
public IndicationBar(Context context) {
super(context);
init();
}
public IndicationBar(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public IndicationBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
#Override
protected void onRestoreInstanceState(Parcelable state) {
Bundle bundle = (Bundle) state;
Parcelable superState = bundle.getParcelable("superState");
super.onRestoreInstanceState(superState);
}
private void init() {
initDrawingTools();
}
// private String getTitle() {
// return "DANCER";
// }
private void Sviesos(){
//Rect = new RectF(0.1f, 0.1f, 0.9f, 0.9f);
//rectPaint = new Paint();
//valueSviesos = BluetoothChat.statusSviesos;
switch(BluetoothChat.statusSviesos){
case 0 : rectPaint.setColor(Color.parseColor("#1BA1E2"));
break;
case 1 : rectPaint.setColor(Color.parseColor("#A05000"));
break;
case 2 : rectPaint.setColor(Color.parseColor("#E671B8"));
break;
case 3 : rectPaint.setColor(Color.parseColor("#F09609"));
break;
case 4 : rectPaint.setColor(Color.parseColor("#1BA1E2"));
break;
}
//rectPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
}
private void initDrawingTools() {
Rect = new RectF(0.1f, 0.1f, 0.9f, 0.9f);
rectPaint = new Paint();
rectPaint.setColor(Color.parseColor("#8CBF26"));
rectPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
Sviesos();
rimCirclePaint = new Paint();
rimCirclePaint.setAntiAlias(true);
rimCirclePaint.setStyle(Paint.Style.STROKE);
rimCirclePaint.setColor(Color.argb(0x4f, 0x33, 0x36, 0x33));
rimCirclePaint.setStrokeWidth(0.005f);
float rimSize = 0.02f;
faceRect = new RectF();
faceRect.set(Rect.left + rimSize, Rect.top + rimSize,
Rect.right - rimSize, Rect.bottom - rimSize);
faceTexture = BitmapFactory.decodeResource(getContext().getResources(),
R.drawable.plastic);
BitmapShader paperShader = new BitmapShader(faceTexture,
Shader.TileMode.MIRROR,
Shader.TileMode.MIRROR);
Matrix paperMatrix = new Matrix();
facePaint = new Paint();
facePaint.setFilterBitmap(true);
paperMatrix.setScale(1.0f / faceTexture.getWidth(),
1.0f / faceTexture.getHeight());
paperShader.setLocalMatrix(paperMatrix);
facePaint.setStyle(Paint.Style.FILL);
facePaint.setShader(paperShader);
rimShadowPaint = new Paint();
rimShadowPaint.setShader(new RadialGradient(0.5f, 0.5f, faceRect.width() / 2.0f,
new int[] { 0x00000000, 0x00000500, 0x50000500 },
new float[] { 0.96f, 0.96f, 0.99f },
Shader.TileMode.MIRROR));
rimShadowPaint.setStyle(Paint.Style.FILL);
titlePaint = new Paint();
titlePaint.setColor(Color.parseColor("#1BA1E2"));
titlePaint.setAntiAlias(true);
titlePaint.setTypeface(Typeface.DEFAULT_BOLD);
titlePaint.setTextAlign(Paint.Align.CENTER);
titlePaint.setTextSize(0.09f);
titlePaint.setTextScaleX(0.9f);
titlePath = new Path();
titlePath.addArc(new RectF(0.24f, 0.24f, 0.76f, 0.76f), -180.0f, -180.0f);
logoPaint = new Paint();
logoPaint.setFilterBitmap(true);
logo = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.sviesos);
logoMatrix = new Matrix();
logoScale = (1.0f / logo.getWidth()) * 0.3f;;
logoMatrix.setScale(logoScale, logoScale);
backgroundPaint = new Paint();
backgroundPaint.setFilterBitmap(true);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Log.d(TAG, "Width spec: " + MeasureSpec.toString(widthMeasureSpec));
Log.d(TAG, "Height spec: " + MeasureSpec.toString(heightMeasureSpec));
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int chosenWidth = chooseDimension(widthMode, widthSize);
int chosenHeight = chooseDimension(heightMode, heightSize);
int chosenDimension = Math.min(chosenWidth, chosenHeight);
setMeasuredDimension(chosenDimension, chosenDimension);
}
private int chooseDimension(int mode, int size) {
if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
return size;
} else { // (mode == MeasureSpec.UNSPECIFIED)
return getPreferredSize();
}
}
// in case there is no size specified
private int getPreferredSize() {
return 300;
}
private void drawRect(Canvas canvas) {
// first, draw the metallic body
canvas.drawRect(Rect, rectPaint);
// now the outer rim circle
//canvas.drawOval(rimRect, rimCirclePaint);
}
// private void drawFace(Canvas canvas) {
// canvas.drawOval(faceRect, facePaint);
// // draw the inner rim circle
// canvas.drawOval(faceRect, rimCirclePaint);
// // draw the rim shadow inside the face
// canvas.drawOval(faceRect, rimShadowPaint);
// }
private void drawBackground(Canvas canvas) {
if (background == null) {
Log.w(TAG, "Background not created");
} else {
canvas.drawBitmap(background, 0, 0, backgroundPaint);
}
}
#Override
protected void onDraw(Canvas canvas) {
drawBackground(canvas);
float scale = (float) getWidth();
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.scale(scale, scale);
drawLogo(canvas);
canvas.restore();
}
private void drawLogo(Canvas canvas) {
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.translate(0.5f - logo.getWidth() * logoScale / 2.0f,
0.5f - logo.getHeight() * logoScale / 2.0f);
canvas.drawBitmap(logo, logoMatrix, logoPaint);
canvas.restore();
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
Log.d(TAG, "Size changed to " + w + "x" + h);
regenerateBackground();
}
private void regenerateBackground() {
// free the old bitmap
Sviesos();
if (background != null) {
background.recycle();
}
background = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
Canvas backgroundCanvas = new Canvas(background);
float scale = (float) getWidth();
backgroundCanvas.scale(scale, scale);
drawRect(backgroundCanvas);
}
}
Use the Observer pattern for this. Change the BluetoothChat
public class BluetoothChat {
private static int statusSviesos;
//the list of observers
private static List<Observer> observerList;
//adds an observer to observe statusSciesos
public static void addStatusSviesosObserver(Observer observer) {
observerList.add(observer);
}
//getter function returns the value
public static int getStatusSviesos(){
return statusSviesos;
}
//setter function sets the value and notifies observer
public static void setStatusSviesos(int statusSviesos){
BluetoothChat.statusSviesos=statusSviesos;
for(Observer current: observerList){
current.notifyChange(statusSviesos);
}
}
public static interface Observer {
public void notifyChange(int newStatus);
}
...
Then create an Observer in the IndicationBar and add it to the BluetoothChat:
Observer observer = new Observer() {
#Override
public void notifyChange(int newStatus) {
Sviesos();
}
};
BluetoothChat.addStatusSviesosObserver(observer);
This is a raw implementation of the Observer pattern. There should be a removeObserver-method too and it is not thread-safe. There is a default implementations ready in Java (Observer-class and Observable-class) and there are alternative implementations like PropertyChangeObserver. But for your current use case this should do the job. Also read Wikipedia and Vogellas tutorial
General tips:
Does BluetoothChat's attribute really has to be static? I recommend you to use static as less as possible. Better create an Object once and pass it around instead. You can search for "global state" and why to avoid it for further information.
You could create an array of Colors (or Color-strings like "#F09609") and access it with the int you get to get rid of the switch-statement.
Try to apply code style conventions everywhere, method names and variables should always start with a small letter (except constants which are ALL_BIG) and should be descriptive.
Im trying to use Neil Davies's CoverFlow Widget v2 as a fragment activity.
Im expecting something like this
Instead Im getting this
Clearly something is wrong in my implementation, but since Im seeing no errors or crashes..Im kinda lost as to where to look. Anywho below is the java and xml code
SampleTabsDefault.java
public class SampleTabsDefault extends FragmentActivity {
private static final String[] CONTENT = new String[] { "Tab 1", "Tab 2", "Tab 3", "Tab 4", "Tab 5", "Tab 6",
"Tab 7","Tab 8","Tab 9","Tab 10","Tab 11","Tab 12","Tab 13","Tab 14"
,"Tab 15","Tab 16"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simple_tabs_2);
FragmentPagerAdapter adapter = new MyNavTabs(getSupportFragmentManager());
ViewPager pager = (ViewPager)findViewById(R.id.pager);
pager.setAdapter(adapter);
TabPageIndicator indicator = (TabPageIndicator)findViewById(R.id.indicator);
indicator.setViewPager(pager);
}
class MyNavTabs extends FragmentPagerAdapter {///////maybe this needs to be in fragment to to call CoverFlowExampleFragment
public MyNavTabs(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch(position)
{
case 0:
TestFragment fragment = new TestFragment();
return fragment;
case 1:
TestFragment2 fragment2 = new TestFragment2();
return fragment2;
}
TestFragment3 fragment3 = new TestFragment3();
return fragment3;
}
#Override
public CharSequence getPageTitle(int position) {
return CONTENT[position % CONTENT.length].toUpperCase();
}
#Override
public int getCount() {
return CONTENT.length;
}
}public void onBackPressed() {
finish();
super.onBackPressed();
}
}
simple_tabs_2.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.viewpagerindicator.TabPageIndicator
android:id="#+id/indicator"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
/>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#drawable/bkg_gradient"/>
</LinearLayout>
TestFragment2.java
public final class TestFragment2 extends Fragment {
TextView et;
TextView text;
SharedPreferences sp;
View myView;
CheckBox cb;
int counter_score;
int counter_score_this;
int counter_score_b;
int counter_score_c;
int counter_score_d;
int counter_score_e;
int GotSaved_ABC, GotSaved_EYE;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
counter_score=0;
counter_score_this =0;
counter_score_b =0;
counter_score_c =0;
counter_score_d =0;
counter_score_e =0;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View myView = inflater.inflate(R.layout.fragment_2, container, false);
text = (TextView)myView.findViewById(R.id.textView1);
et = (TextView)myView.findViewById(R.id.textView3);
cb = (CheckBox) myView.findViewById(R.id.checkBox1);
/// FragmentPagerAdapter adapter = new ScrollGallery(getChildFragmentManager());
/// ViewPager pager = (ViewPager)myView.findViewById(R.id.pager);
// pager.setAdapter(adapter);
//TabPageIndicator indicator = (TabPageIndicator)myView.findViewById(R.id.indicator);
//indicator.setViewPager(pager);
CoverFlow mycoverFlow = new CoverFlow(getActivity());
mycoverFlow.setAdapter(new ImageAdapter(getActivity()));
ImageAdapter coverImageAdapter = new ImageAdapter(getActivity());
//coverImageAdapter.createReflectedImages();
mycoverFlow.setAdapter(coverImageAdapter);
mycoverFlow.setSpacing(-25);
mycoverFlow.setSelection(4, true);
mycoverFlow.setAnimationDuration(1000);
loadPrefs();
return myView;
}
private void loadPrefs() {
int questions_int =156;
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
GotSaved_ABC = sp.getInt("NAME", GotSaved_ABC);
GotSaved_EYE = sp.getInt("NAME2", GotSaved_EYE);
counter_score = GotSaved_ABC;
counter_score_this =GotSaved_EYE;
//////counter_score_2 = make it equal to whatever..
int percentage = (int)( GotSaved_ABC + GotSaved_EYE * 100.0 / questions_int + 0.5);
text.setText(percentage +"%");
//}
///class ScrollGallery extends FragmentPagerAdapter {///////this maybe needs to be in fragment to to call CoverFlowExampleFragment
// public ScrollGallery(FragmentManager fm) {
// super(fm);
/// }
//#Override
// public Fragment getItem(int position) {
// return CoverFlowExampleFragment.getActivity();
}
public class ImageAdapter extends BaseAdapter {
int mGalleryItemBackground;
private Context mContext;
private FileInputStream fis;
private Integer[] mImageIds = {
R.drawable.kasabian_kasabian,
R.drawable.starssailor_silence_is_easy,
R.drawable.killers_day_and_age,
R.drawable.garbage_bleed_like_me,
R.drawable.death_cub_for_cutie_the_photo_album,
R.drawable.kasabian_kasabian,
R.drawable.massive_attack_collected,
R.drawable.muse_the_resistance,
R.drawable.starssailor_silence_is_easy
};
private ImageView[] mImages;
public ImageAdapter(Context c) {
mContext = c;
mImages = new ImageView[mImageIds.length];
}
public boolean createReflectedImages() {
//The gap we want between the reflection and the original image
final int reflectionGap = 4;
int index = 0;
for (int imageId : mImageIds) {
Bitmap originalImage = BitmapFactory.decodeResource(getResources(),
imageId);
int width = originalImage.getWidth();
int height = originalImage.getHeight();
//This will not scale but will flip on the Y axis
Matrix matrix = new Matrix();
matrix.preScale(1, -1);
//Create a Bitmap with the flip matrix applied to it.
//We only want the bottom half of the image
Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0, height/2, width, height/2, matrix, false);
//Create a new bitmap with same width but taller to fit reflection
Bitmap bitmapWithReflection = Bitmap.createBitmap(width
, (height + height/2), Config.ARGB_8888);
//Create a new Canvas with the bitmap that's big enough for
//the image plus gap plus reflection
Canvas canvas = new Canvas(bitmapWithReflection);
//Draw in the original image
canvas.drawBitmap(originalImage, 0, 0, null);
//Draw in the gap
Paint deafaultPaint = new Paint();
canvas.drawRect(0, height, width, height + reflectionGap, deafaultPaint);
//Draw in the reflection
canvas.drawBitmap(reflectionImage,0, height + reflectionGap, null);
//Create a shader that is a linear gradient that covers the reflection
Paint paint = new Paint();
LinearGradient shader = new LinearGradient(0, originalImage.getHeight(), 0,
bitmapWithReflection.getHeight() + reflectionGap, 0x70ffffff, 0x00ffffff,
TileMode.CLAMP);
//Set the paint to use this shader (linear gradient)
paint.setShader(shader);
//Set the Transfer mode to be porter duff and destination in
paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
//Draw a rectangle using the paint with our linear gradient
canvas.drawRect(0, height, width,
bitmapWithReflection.getHeight() + reflectionGap, paint);
ImageView imageView = new ImageView(mContext);
imageView.setImageBitmap(bitmapWithReflection);
imageView.setLayoutParams(new CoverFlow.LayoutParams(120, 180));
imageView.setScaleType(ScaleType.MATRIX);
mImages[index++] = imageView;
}
return true;
}
public int getCount() {
return mImageIds.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
//Use this code if you want to load from resources
ImageView i = new ImageView(mContext);
i.setImageResource(mImageIds[position]);
i.setLayoutParams(new CoverFlow.LayoutParams(130, 130));
i.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
//Make sure we set anti-aliasing otherwise we get jaggies
BitmapDrawable drawable = (BitmapDrawable) i.getDrawable();
drawable.setAntiAlias(true);
return i;
//return mImages[position];
}
/** Returns the size (0.0f to 1.0f) of the views
* depending on the 'offset' to the center. */
public float getScale(boolean focused, int offset) {
/* Formula: 1 / (2 ^ offset) */
return Math.max(0, 1.0f / (float)Math.pow(2, Math.abs(offset)));
}
}
//#Override
///public int getCount() {
// TODO Auto-generated method stub
//return 0;
//}
}
fragment_2.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:weightSum="3" android:orientation="horizontal" android:layout_gravity="center_horizontal" >
<CheckBox
android:id="#+id/checkBox1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Check this box" />
<TextView
android:id="#+id/textView1"
android:layout_width="200dp"
android:layout_height="180dp"
android:layout_marginLeft="-55dp"
android:layout_marginTop="112dp"
android:background="#drawable/blue_main_score"
android:gravity="center_horizontal|center_vertical"
android:text="0"
android:shadowColor="#android:color/black"
android:shadowRadius="7.0"
android:shadowDx="1.0"
android:shadowDy="1.0"
android:textColor="#f5f5f5f5"
android:textSize="50dp"
android:textStyle="bold"
android:visibility="visible" />
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="left"
android:text="Fragment TEST"
android:textSize="48sp"
android:id="#+id/textView3"/>
</LinearLayout>
</LinearLayout>
*edit forgot the CoverFlow.java
public class CoverFlow extends Gallery {
/**
* Graphics Camera used for transforming the matrix of ImageViews
*/
private Camera mCamera = new Camera();
/**
* The maximum angle the Child ImageView will be rotated by
*/
private int mMaxRotationAngle = 90;
/**
* The maximum zoom on the centre Child
*/
private int mMaxZoom = -500;
/**
* The Centre of the Coverflow
*/
private int mCoveflowCenter;
public CoverFlow(Context context) {
super(context);
this.setStaticTransformationsEnabled(true);
}
public CoverFlow(Context context, AttributeSet attrs) {
super(context, attrs);
this.setStaticTransformationsEnabled(true);
}
public CoverFlow(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.setStaticTransformationsEnabled(true);
}
/**
* Get the max rotational angle of the image
* #return the mMaxRotationAngle
*/
public int getMaxRotationAngle() {
return mMaxRotationAngle;
}
/**
//* Set the max rotational angle of each image
* #param maxRotationAngle the mMaxRotationAngle to set
*/
public void setMaxRotationAngle(int maxRotationAngle) {
mMaxRotationAngle = maxRotationAngle;
}
/**
* Get the Max zoom of the centre image
* #return the mMaxZoom
*/
public int getMaxZoom() {
return mMaxZoom;
}
/**
* Set the max zoom of the centre image
* #param maxZoom the mMaxZoom to set
*/
public void setMaxZoom(int maxZoom) {
mMaxZoom = maxZoom;
}
/**
* Get the Centre of the Coverflow
* #return The centre of this Coverflow.
*/
private int getCenterOfCoverflow() {
return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2 + getPaddingLeft();
}
/**
* Get the Centre of the View
* #return The centre of the given view.
*/
private static int getCenterOfView(View view) {
return view.getLeft() + view.getWidth() / 2;
}
/**
* {#inheritDoc}
*
* #see #setStaticTransformationsEnabled(boolean)
*/
protected boolean getChildStaticTransformation(View child, Transformation t) {
final int childCenter = getCenterOfView(child);
final int childWidth = child.getWidth() ;
int rotationAngle = 0;
t.clear();
t.setTransformationType(Transformation.TYPE_MATRIX);
if (childCenter == mCoveflowCenter) {
transformImageBitmap((ImageView) child, t, 0);
} else {
rotationAngle = (int) (((float) (mCoveflowCenter - childCenter)/ childWidth) * mMaxRotationAngle);
if (Math.abs(rotationAngle) > mMaxRotationAngle) {
rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle : mMaxRotationAngle;
}
transformImageBitmap((ImageView) child, t, rotationAngle);
}
return true;
}
/**
* This is called during layout when the size of this view has changed. If
* you were just added to the view hierarchy, you're called with the old
* values of 0.
*
* #param w Current width of this view.
* #param h Current height of this view.
* #param oldw Old width of this view.
* #param oldh Old height of this view.
*/
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
mCoveflowCenter = getCenterOfCoverflow();
super.onSizeChanged(w, h, oldw, oldh);
}
/**
* Transform the Image Bitmap by the Angle passed
*
* #param imageView ImageView the ImageView whose bitmap we want to rotate
* #param t transformation
* #param rotationAngle the Angle by which to rotate the Bitmap
*/
private void transformImageBitmap(ImageView child, Transformation t, int rotationAngle) {
mCamera.save();
final Matrix imageMatrix = t.getMatrix();;
final int imageHeight = child.getLayoutParams().height;;
final int imageWidth = child.getLayoutParams().width;
final int rotation = Math.abs(rotationAngle);
mCamera.translate(0.0f, 0.0f, 100.0f);
//As the angle of the view gets less, zoom in
if ( rotation < mMaxRotationAngle ) {
float zoomAmount = (float) (mMaxZoom + (rotation * 1.5));
mCamera.translate(0.0f, 0.0f, zoomAmount);
}
mCamera.rotateY(rotationAngle);
mCamera.getMatrix(imageMatrix);
imageMatrix.preTranslate(-(imageWidth/2), -(imageHeight/2));
imageMatrix.postTranslate((imageWidth/2), (imageHeight/2));
mCamera.restore();
}
}
A lot of code :-)
In your TestFragment2.java, there seems to be one big error (could explain why you don't see your CoverFlow) and another smaller one.
In your onCreateView method of TestFragment2, you forget to add your mycoverFlow to the view hierarchy.
Add this to your onCreateView method and see if this fixes it (partially):
((ViewGroup)myView).addView(mycoverFlow, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
(maybe MATCH_PARENT should be WRAP_CONTENT).
A smaller error is that in this onCreateView method, you call mycoverFlow.setAdapter(...) twice. Only the last one has effect. Remove the first one.