I am trying to create a simple ball and stick game in android and have the following xml file for android.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".BallActivity">
<learn.com.application.BallView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/ball"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Left"
android:onClick="moveleft"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Right"
android:onClick="moveright"/>
</LinearLayout>
</LinearLayout>
The LinearLayout containing the buttons is not visible as the BallView is match_parent. But if i declare height of BallView as wrap_content It does not work. How can i show the left and right buttons on the bottom. What else can i use for moving the stick left or right.
Code for BallView
public class BallView extends android.support.v7.widget.AppCompatImageView {
private Context mContext;
int x = -1;
int y = -1;
boolean first=true;
private int xVelocity = 10;
private int yVelocity = 5;
private Handler h;
public static int FRAME_RATE = 50;
public static int stickx=0,sticky=0;
public static int width=0;
public static int height=0;
boolean gameover=false;
public BallView(Context context,AttributeSet s) {
super(context,s);
mContext=context;
h=new Handler();
}
private Runnable r=new Runnable() {
#Override
public void run() {
invalidate();
}
};
#Override
protected void onDraw(Canvas canvas) {
if(first) {
stickx = getWidth() / 2 - 40;
sticky = getHeight() - 60;
width = getWidth();
height = getHeight();
first=false;
}
Bitmap bmp= BitmapFactory.decodeResource(mContext.getResources(),R.drawable.ball1);
if(x<0 && y<0)
{
x=getWidth()/2;
y=getHeight()/2;
}
else {
x += xVelocity;
y += yVelocity;
if (x + bmp.getWidth() > getWidth() || (x < 0))
xVelocity = xVelocity * -1;
if (y < 0)
yVelocity = yVelocity * -1;
if (y + bmp.getHeight() >= sticky) {
if (x + bmp.getWidth() > stickx && x + bmp.getWidth() < (stickx + 180)) {
yVelocity = yVelocity * -1;
Log.v("ball","collision");
}
else {
Log.v("ball", "game over");
gameover=true;
}
}
}
RectF rr=new RectF();
int right=stickx+180;
int bottom=sticky+30;
rr.set(stickx,sticky,right,bottom);
Paint p=new Paint();
canvas.drawRoundRect(rr,5,5,p);
canvas.drawBitmap(bmp,x,y,null);
if(!gameover)
h.postDelayed(r,FRAME_RATE);
}
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".BallActivity">
<learn.com.application.BallView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/tablerow"
android:id="#+id/ball"/>
<TableRow
android:id="#+id/tablerow"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Left"
android:onClick="moveleft"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Right"
android:onClick="moveright"/>
</TableRow>
</RelativeLayout>
Instead of using LinearLayout, I would prefer to use RelativeLayout and TableRow as shown
Related
I am building a custom EditText from this answer, this is the output I am getting,
Problem
The lines are not starting right at the top,they are starting somewhere in the middle, what could be wrong.
Here is the code,
public class LinedEditText extends EditText {
private static Paint linePaint;
static {
linePaint = new Paint();
linePaint.setColor(Color.BLACK);
linePaint.setStyle(Paint.Style.STROKE);
}
public LinedEditText(Context context, AttributeSet attributes) {
super(context, attributes);
}
#Override
protected void onDraw(Canvas canvas) {
Rect bounds = new Rect();
int firstLineY = getLineBounds(0, bounds);
int lineHeight = getLineHeight();
int totalLines = Math.max(getLineCount(), getHeight() / lineHeight);
for (int i = 0; i < totalLines; i++) {
int lineY = firstLineY + i * lineHeight;
canvas.drawLine(bounds.left, lineY, bounds.right, lineY, linePaint);
}
super.onDraw(canvas);
}
}
Here is my XML,
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/PeachPuff"
>
<TextView
android:layout_width="match_parent"
android:gravity="center"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Large Text"
android:id="#+id/textView"
android:padding="8dp"
android:layout_margin="10dp"
android:background="#drawable/shape"
android:layout_gravity="center_horizontal" />
<com.random.simplenotes.LinedEditText
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
All I did was added the gravity and everything was fine,
<com.random.simplenotes.LinedEditText
android:layout_width="match_parent"
android:layout_height="match_parent"
android:inputType="textMultiLine"
android:gravity="top|left"
/>
I try to create a collapsing layout on scroll, but I encounter an issue with my avatar, indeed when the CircleImageView is inside my AppBarLayout, nothing happens, I need to put it below my ToolbarLayout, here is my xml to be clearer :
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/coordinator_layout_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="RtlHardcoded">
<android.support.design.widget.AppBarLayout
android:id="#+id/main.appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/main.collapsing"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<RelativeLayout
android:id="#+id/relative_layout_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="#dimen/activity_vertical_margin">
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/circle_image_view_avatar"
android:layout_width="#dimen/menu_size_avatar"
android:layout_height="#dimen/menu_size_avatar"
android:layout_gravity="center"
android:layout_centerHorizontal="true"
android:layout_marginTop="#dimen/profile_margin_top_avatar"
android:src="#drawable/avatar_6"
app:civ_border_color="#color/white"
app:civ_border_width="#dimen/avatar_border_width"
app:finalHeight="#dimen/image_final_width"
app:layout_collapseMode="parallax"
app:layout_behavior="com.example.AvatarImageBehavior"
app:startHeight="2dp"
app:startToolbarPosition="2dp"
app:startXPosition="2dp" />
<FrameLayout
android:id="#+id/frame_layout_ranking"
android:layout_width="47dp"
android:layout_height="47dp"
android:layout_alignLeft="#id/circle_image_view_avatar"
android:layout_alignStart="#id/circle_image_view_avatar"
android:layout_alignTop="#id/circle_image_view_avatar">
<ImageView
android:layout_width="#dimen/profile_button_ranking_trophies_size"
android:layout_height="#dimen/profile_button_ranking_trophies_size"
android:background="#drawable/circle_white"
android:scaleType="centerInside"
android:src="#drawable/ic_classement" />
</FrameLayout>
<FrameLayout
android:id="#+id/frame_layout_trophies"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignEnd="#id/circle_image_view_avatar"
android:layout_alignRight="#id/circle_image_view_avatar"
android:layout_alignTop="#id/circle_image_view_avatar">
<ImageView
android:layout_width="#dimen/profile_button_ranking_trophies_size"
android:layout_height="#dimen/profile_button_ranking_trophies_size"
android:background="#drawable/circle_white"
android:scaleType="centerInside"
android:src="#drawable/ic_trophees" />
</FrameLayout>
<FrameLayout
android:id="#+id/frame_layout_level"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/circle_image_view_avatar"
android:layout_centerHorizontal="true">
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/circle_image_view_level"
android:layout_width="#dimen/menu_size_level"
android:layout_height="#dimen/menu_size_level"
app:civ_border_color="#color/white"
app:civ_border_width="#dimen/avatar_border_width" />
</FrameLayout>
<TextView
android:id="#+id/text_view_pseudo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/frame_layout_level"
android:layout_centerHorizontal="true"
android:maxLines="2"
android:textAllCaps="true"
android:textColor="#color/white"
android:textSize="#dimen/font_32" />
</RelativeLayout>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<!-- Content -->
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:scrollbars="none">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingTop="#dimen/activity_vertical_margin">
....
</LinearLayout>
</android.support.v7.widget.CardView>
</android.support.v4.widget.NestedScrollView>
<!-- Final toolbar -->
<android.support.v7.widget.Toolbar
android:id="#+id/main.toolbar"
android:layout_width="match_parent"
android:layout_height="54dp"
android:background="#5025A5FF"
app:layout_anchor="#id/text_view_pseudo"
app:layout_anchorGravity="center_vertical"
app:theme="#style/ThemeOverlay.AppCompat.Dark"
app:title="">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:maxLines="2"
android:textAllCaps="true"
android:text="Pseudo"
android:textColor="#color/white"
android:textSize="#dimen/font_18" />
</LinearLayout>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CoordinatorLayout>
Here is the code of my AvatarImageBehavior class :
import android.content.Context;
import android.content.res.TypedArray;
import android.support.design.widget.CoordinatorLayout;
import android.support.v7.widget.Toolbar;
import android.util.AttributeSet;
import android.view.View;
import com.example.R;
import de.hdodenhof.circleimageview.CircleImageView;
#SuppressWarnings("unused")
public class AvatarImageBehavior extends CoordinatorLayout.Behavior<CircleImageView> {
private final static float MIN_AVATAR_PERCENTAGE_SIZE = 0.3f;
private final static int EXTRA_FINAL_AVATAR_PADDING = 80;
private final static String TAG = "behavior";
private Context mContext;
private float mCustomFinalXPosition;
private float mCustomFinalYPosition;
private float mCustomStartXPosition;
private float mCustomStartToolbarPosition;
private float mCustomStartHeight;
private float mCustomFinalHeight;
private float mAvatarMaxSize;
private float mFinalLeftAvatarPadding;
private float mStartPosition;
private int mStartXPosition;
private float mStartToolbarPosition;
private int mStartYPosition;
private int mFinalYPosition;
private int mStartHeight;
private int mFinalXPosition;
private float mChangeBehaviorPoint;
public AvatarImageBehavior(Context context, AttributeSet attrs) {
mContext = context;
if (attrs != null) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AvatarImageBehavior);
mCustomStartXPosition = a.getDimension(R.styleable.AvatarImageBehavior_startXPosition, 0);
mCustomStartToolbarPosition = a.getDimension(R.styleable.AvatarImageBehavior_startToolbarPosition, 0);
mCustomStartHeight = a.getDimension(R.styleable.AvatarImageBehavior_startHeight, 0);
mCustomFinalHeight = a.getDimension(R.styleable.AvatarImageBehavior_finalHeight, 0);
a.recycle();
}
init();
mFinalLeftAvatarPadding = context.getResources().getDimension(R.dimen.activity_vertical_little_margin);
}
private void init() {
bindDimensions();
}
private void bindDimensions() {
mAvatarMaxSize = mContext.getResources().getDimension(R.dimen.game_answer_bonus);
}
#Override
public boolean layoutDependsOn(CoordinatorLayout parent, CircleImageView child, View dependency) {
return dependency instanceof Toolbar;
}
#Override
public boolean onDependentViewChanged(CoordinatorLayout parent, CircleImageView child, View dependency) {
maybeInitProperties(child, dependency);
final int maxScrollDistance = (int) (mStartToolbarPosition);
float expandedPercentageFactor = dependency.getY() / maxScrollDistance;
if (expandedPercentageFactor < mChangeBehaviorPoint) {
float heightFactor = (mChangeBehaviorPoint - expandedPercentageFactor) / mChangeBehaviorPoint;
float distanceXToSubtract = ((mStartXPosition - mFinalXPosition) * heightFactor) + (child.getHeight()/2);
float distanceYToSubtract = ((mStartYPosition - mFinalYPosition) * (1f - expandedPercentageFactor)) + (child.getHeight()/2);
child.setX(mStartXPosition - distanceXToSubtract);
child.setY(mStartYPosition - distanceYToSubtract);
float heightToSubtract = ((mStartHeight - mCustomFinalHeight) * heightFactor);
CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) child.getLayoutParams();
lp.width = (int) (mStartHeight - heightToSubtract);
lp.height = (int) (mStartHeight - heightToSubtract);
child.setLayoutParams(lp);
} else {
float distanceYToSubtract = ((mStartYPosition - mFinalYPosition) * (1f - expandedPercentageFactor)) + (mStartHeight/2);
child.setX(mStartXPosition - child.getWidth()/2);
child.setY(mStartYPosition - distanceYToSubtract);
CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) child.getLayoutParams();
lp.width = (int) (mStartHeight);
lp.height = (int) (mStartHeight);
child.setLayoutParams(lp);
}
return true;
}
private void maybeInitProperties(CircleImageView child, View dependency) {
if (mStartYPosition == 0) {
// mStartYPosition = (int) (dependency.getY());
mStartYPosition = 185;
}
if (mFinalYPosition == 0)
mFinalYPosition = (dependency.getHeight() /2);
if (mStartHeight == 0)
mStartHeight = child.getHeight();
if (mStartXPosition == 0)
mStartXPosition = (int) (child.getX() + (child.getWidth() / 2));
if (mFinalXPosition == 0) {
// mFinalXPosition = mContext.getResources().getDimensionPixelOffset(R.dimen.abc_action_bar_content_inset_material) + ((int) mCustomFinalHeight / 2);
mFinalXPosition = (int) (dependency.getWidth() - mContext.getResources().getDimension(R.dimen.image_final_width) + mContext.getResources().getDimension(R.dimen.profile_toolbar_margin_right));
}
if (mStartToolbarPosition == 0)
mStartToolbarPosition = dependency.getY();
if (mChangeBehaviorPoint == 0) {
mChangeBehaviorPoint = (child.getHeight() - mCustomFinalHeight) / (2f * (mStartYPosition - mFinalYPosition));
}
}
public int getStatusBarHeight() {
int result = 0;
int resourceId = mContext.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = mContext.getResources().getDimensionPixelSize(resourceId);
}
return result;
}
}
Do you see why, my CircleImageView react only when it's outside the AppBarLayout. I need it to be inside because, my FrameLayout are views over the CircleImageView (an avatar). I begin with CoordinatorLayout so maybe I miss something.
Regards.
historically i have stupid problems with layouts, and now i try to fill this blank in my brain. Watch this example, i try to do some axis for graphic, and i want to pack them like this:
Vertical line by left side
Horizontal line by bottom
Spacer between Vert & Horiz in left bottom corner
Other place fill by graph
(Sorry not allowed to post images.I hope you see graphics axis before, no need to explain.)
And this what i got at now:
<?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:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<com.example.graphicformatting.Axis
android:id="#+id/yaxis"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginBottom="40dp"
android:background="#color/backpanel_dark"
custom:ishorizontal="false" />
<EditText
android:id="#+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textMultiLine"
android:text="This text field mean my own graphic widget, which not have any OnMeasured function or any specific and it's painting with size, which assigment by parent/ Just use getHeight and getWeight" >
<requestFocus />
</EditText>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<View
android:layout_width="40dp"
android:layout_height="40dp"
android:background="#color/backpanel_dark" />
<com.example.graphicformatting.Axis
android:id="#+id/yaxis"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="40dp"
android:background="#color/backpanel_dark"
custom:ishorizontal="true" />
</LinearLayout>
And this is code of my axises:
package com.example.graphicformatting;
public class Axis extends View {
public static final int HORIZONTAL = 0;
public static final int VERTICAL = 1;
public static final int DP_SIZE = 40;
int type = -1;
int size;
Paint painter;
public Axis(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.com_example_graphicformatting_Axis);
final int N = a.getIndexCount();
for (int i = 0; i < N; ++i) {
int attr = a.getIndex(i);
switch (attr) {
case R.styleable.com_example_graphicformatting_Axis_ishorizontal:
if (a.getBoolean(attr, true)) {
type = HORIZONTAL;
} else
type = VERTICAL;
break;
default:
Log.d("axis", "Found unexpected state");
}
}
a.recycle();
final float scale = getContext().getResources().getDisplayMetrics().density;
size = (int) (DP_SIZE * scale + 0.5f);
painter = new Paint();
painter.setColor(Color.RED);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
if (type == HORIZONTAL) {
this.setMeasuredDimension(parentWidth, size);
this.setLayoutParams(new LinearLayout.LayoutParams(parentWidth, size));
// Log.d("axis", "Size of horizontal calc: " + (parentWidth) + " "
// + size);
} else if (type == VERTICAL) {
this.setMeasuredDimension(size, parentHeight);
this.setLayoutParams(new LinearLayout.LayoutParams(size, parentHeight));
// Log.d("axis", "Size of vertical calc: " + size + " "
// + (parentHeight));
} else { // Для нормального отображения в конструкторе
this.setMeasuredDimension(size, size);
this.setLayoutParams(new LinearLayout.LayoutParams(size, size));
}
}
#Override
protected void onDraw(Canvas canvas) {
if (type == VERTICAL) {
canvas.drawRect(0, 0, size, getHeight(), painter);
} else {
canvas.drawRect(0, getHeight() - size, getWidth(), getHeight(), painter);
}
super.onDraw(canvas);
}
}
How to custom my Layouts to get right pic?
Ou, this using for set horizontal/vertical attribute (value/attrs.xml)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="com.example.graphicformatting.Axis">
<attr name="ishorizontal" format="boolean"></attr>
</declare-styleable>
</resources>
when move the image from bottom to up with animation,not getting the full image,i am declaring imageview width wrap content.when i was moving the down its working perfectly,but when i image dragging up,the showing part comes with animation not getting the full image.
public class MainActivity extends Activity {
// mainLayout is the child of the HorizontalScrollView ...
private LinearLayout mainLayout;
// this is an array that holds the IDs of the drawables ...
private int[] images = { R.drawable.gg, R.drawable.gg, R.drawable.gg,
R.drawable.gg, R.drawable.gg, R.drawable.gg };
int status = 0;
int Measuredwidth = 0, MeasuredHeight = 0;
float x = 0;
boolean first = true;
ImageButton btn;
View cell = null;
Matrix matrix = new Matrix();
Matrix savedMatrix = new Matrix();
PointF startPoint = new PointF();
static final int NONE = 0;
static final int DRAG = 1;
Bitmap icon;
int mode = NONE;
AnimationListener animx;
/** Called when the activity is first created. */
#TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.activity_main);
mainLayout = (LinearLayout) findViewById(R.id.linearLayout);
for (int i = 0; i < images.length; i++) {
cell = getLayoutInflater().inflate(R.layout.image, null);
final ImageView img = (ImageView) cell.findViewById(R.id.imageView);
img.setImageResource(images[i]);
// mainLayout.addView(cell);
// }
final LinearLayout ll = (LinearLayout) cell
.findViewById(R.id.lllayout);
Point size = new Point();
WindowManager w = getWindowManager();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
w.getDefaultDisplay().getSize(size);
MeasuredHeight = size.y;
Measuredwidth = size.x;
} else {
Display d = w.getDefaultDisplay();
Measuredwidth = d.getWidth();
MeasuredHeight = d.getHeight();
}
// final AbsoluteLayout aalayout = (AbsoluteLayout) cell
// .findViewById(R.id.absLayout);
btn = (ImageButton) cell.findViewById(R.id.button1);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "button 1 pressed",
2000).show();
}
});
img.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(final View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
status = 0;
System.out.println("sdhsjdkklkl");
} else if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (first) {
x = event.getX();
first = false;
System.out.println("matrix: " + matrix);
savedMatrix.set(matrix);
mode = DRAG;
startPoint.set(img.getLeft(), event.getY());
} else {
startPoint.set(img.getLeft(), event.getY());
}
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
float dx = event.getX() - startPoint.x;
final float dy = event.getY() - startPoint.y;
float setheight = btn.getBottom() + 6;
if (dy > 0) {
System.out.println("saved matrix:" + savedMatrix);
matrix.set(savedMatrix);
System.out.println("y value: " + dy);
matrix.postTranslate(img.getLeft(), 80);
ll.setVisibility(View.VISIBLE);
img.setImageMatrix(matrix);
}
else if (dy < 0) {
int fromLoc[] = new int[2];
img.getLocationOnScreen(fromLoc);
final float startX = fromLoc[0];
final float startY = fromLoc[1];
int toLoc[] = new int[2];
img.getLocationOnScreen(toLoc);
final float destX = 0;
final float destY = img.getTop();
ll.setVisibility(View.GONE);
TranslateAnimation mAnimation = new TranslateAnimation(
0, 0, 0, -80);
mAnimation.setDuration(10000);
mAnimation.setRepeatCount(0);
mAnimation
.setInterpolator(new LinearInterpolator());
mAnimation.setFillAfter(true);
img.setAnimation(mAnimation);
}
}
return true;
}
});
System.out.println("bmgbgklb");
mainLayout.addView(cell);
}
}
}
my main xml is:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<HorizontalScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="1dip" >
<LinearLayout
android:id="#+id/linearLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
</LinearLayout>
</HorizontalScrollView>
</RelativeLayout>
my sub xml is:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_marginRight="2dip"
android:scaleType="matrix"
android:src="#drawable/dd" >
</ImageView>
<LinearLayout
android:id="#+id/lllayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="invisible" >
<ImageButton
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginLeft="20dip"
android:background="#drawable/orangearrow_over"
android:focusable="true" />
<ImageButton
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10dip"
android:layout_marginRight="10dip"
android:background="#drawable/orangearrow_over" />
<ImageButton
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dip"
android:background="#drawable/orangearrow_over" />
</LinearLayout>
</FrameLayout>
I have used FrameLayout within a Gallery as the Gallery Item. There are 2 RelativeLayouts inside the FrameLayout each holding some TextView and an ImageView. There is a button outside the Gallery called 'Flip'. Clicking the button 'Flip' hides one relative layout and shows the another with flip animation. And there is also a TextView outside the Gallery in which I update some text. When the user scrolls the Gallery to select another item, then I update the TextView from Gallery's setOnItemSelected method.
The problem is if I don't update the TextView from the setOnItemSelected method, the flipping animation works correctly. But, if I update the TextView then the animation doesn't work. Even it doesn't switch the RelativeLayout inside the FrameLayout.
If anybody has any idea where the problem please help me.
Here is the XML layout for the main screen:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="top|center" android:background="#0000">
<RelativeLayout android:id="#+id/RelativeLayout04" android:layout_height="fill_parent" android:layout_width="fill_parent"><RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="#drawable/top_bar" android:layout_alignParentTop="true" android:id="#+id/headerRelativeLayout"><Button android:id="#+id/homeButton" android:layout_height="wrap_content" android:layout_marginTop="5dip" android:background="#drawable/home_button_open" android:layout_marginLeft="5dip" android:layout_width="wrap_content" android:layout_alignParentLeft="true"></Button>
<Button android:id="#+id/backButton" android:layout_height="wrap_content" android:layout_marginTop="5dip" android:background="#drawable/back_button" android:layout_toRightOf="#+id/homeButton" android:layout_width="wrap_content"></Button>
<TextView android:layout_height="wrap_content" android:textSize="22sp" android:layout_toLeftOf="#+id/LinearLayout02" android:gravity="center" android:layout_toRightOf="#+id/backButton" android:id="#+id/TextView02" android:layout_width="fill_parent" android:textStyle="bold" android:layout_centerInParent="true"></TextView>
<LinearLayout android:layout_alignParentRight="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_centerVertical="true" android:layout_marginRight="10dip" android:id="#+id/LinearLayout02">
<com.vocabAhead.SATVocab.LoginButton android:layout_marginRight="5dip" android:id="#+id/facebookButton" android:layout_width="wrap_content" android:background="#drawable/facebook_button" android:layout_height="wrap_content"></com.vocabAhead.SATVocab.LoginButton>
<Button android:id="#+id/settingsButton" android:layout_width="wrap_content" android:background="#drawable/settings_button" android:layout_height="wrap_content" android:layout_gravity="center_vertical"></Button>
</LinearLayout>
</RelativeLayout>
<RelativeLayout android:layout_width="fill_parent" android:layout_height="35dip" android:background="#FF212121" android:layout_alignParentBottom="true" android:id="#+id/footerRelativeLayout">
<Button android:id="#+id/playButton" android:layout_height="wrap_content" android:background="#drawable/play_button" android:layout_marginLeft="10dip" android:layout_width="wrap_content" android:layout_centerVertical="true" android:layout_alignParentLeft="true"></Button>
<Button android:layout_alignParentRight="true" android:id="#+id/showScriptButton" android:layout_height="wrap_content" android:background="#drawable/infobutton" android:layout_marginRight="10dip" android:layout_width="wrap_content" android:layout_centerVertical="true"></Button>
<TextView android:layout_height="wrap_content" android:textColor="#FFFF" android:id="#+id/itemSerialTextView" android:layout_width="wrap_content" android:layout_centerInParent="true"></TextView>
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="5dip" android:layout_toRightOf="#+id/playButton" android:id="#+id/durationTextView" android:textColor="#FFFF"></TextView>
</RelativeLayout>
<Gallery android:id="#+id/wordsGallery" android:layout_above="#+id/footerRelativeLayout" android:layout_below="#+id/headerRelativeLayout" android:layout_height="fill_parent" android:layout_width="fill_parent" android:scrollbars="none" android:scrollbarSize="0dip" android:layout_margin="0dip" android:gravity="fill" android:padding="0dip" android:background="#0000"></Gallery>
</RelativeLayout>
</LinearLayout>
And here is the XML layout for the Gallery items:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/container"
android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_margin="0dip" android:padding="0dip">
<RelativeLayout android:layout_height="fill_parent" android:layout_width="fill_parent" android:id="#+id/wordDetailsRelativeLayout" android:background="#FFFF">
<TextView android:gravity="center" android:textSize="18sp" android:layout_alignParentTop="true" android:layout_width="fill_parent" android:text="Apathy" android:textStyle="bold" android:layout_height="wrap_content" android:layout_marginBottom="5dip" android:layout_marginTop="5dip" android:id="#+id/wordTextView" android:textColor="#FF1a3f6e"></TextView>
<TextView android:gravity="center" android:layout_width="fill_parent" android:text="verb" android:layout_height="wrap_content" android:id="#+id/partsOfSpeechTextView" android:layout_below="#+id/wordTextView" android:layout_marginBottom="5dip"></TextView>
<LinearLayout android:paddingBottom="5dip" android:layout_width="fill_parent" android:gravity="center" android:background="#FFFF" android:id="#+id/LinearLayout01" android:layout_height="wrap_content" android:layout_alignParentBottom="true"><ImageView android:src="#drawable/iphone_vocabulary_logo_15" android:id="#+id/logoImageView" android:layout_height="wrap_content" android:layout_width="wrap_content"></ImageView>
</LinearLayout>
<LinearLayout android:layout_height="fill_parent" android:layout_marginBottom="5dip" android:layout_width="fill_parent" android:layout_below="#+id/partsOfSpeechTextView" android:orientation="vertical" android:id="#+id/imageAndMeaningLinearLayout" android:gravity="top|center_horizontal" android:layout_above="#+id/LinearLayout01"><ImageView android:id="#+id/wordImageView" android:layout_height="wrap_content" android:layout_width="wrap_content"></ImageView>
<TextView android:layout_height="wrap_content" android:id="#+id/wordMeaningTextView" android:layout_width="wrap_content" android:textColor="#F000" android:textSize="15sp" android:layout_marginLeft="10dip" android:layout_marginTop="10dip" android:layout_marginRight="10dip" android:gravity="center"></TextView>
</LinearLayout>
</RelativeLayout>
<RelativeLayout android:layout_height="fill_parent" android:layout_width="fill_parent" android:background="#FFFF" android:id="#+id/wordScriptRelativeLayout" android:visibility="gone">
<TextView android:gravity="center" android:textSize="18sp" android:layout_alignParentTop="true" android:layout_width="fill_parent" android:text="Apathy" android:textStyle="bold" android:layout_height="wrap_content" android:layout_marginBottom="5dip" android:layout_marginTop="5dip" android:textColor="#FF1a3f6e" android:id="#+id/wordTextView2"></TextView>
<TextView android:gravity="center" android:layout_width="fill_parent" android:text="verb" android:layout_height="wrap_content" android:id="#+id/partsOfSpeechTextView2" android:layout_below="#+id/wordTextView2" android:layout_marginBottom="5dip"></TextView>
<LinearLayout android:paddingBottom="5dip" android:layout_width="fill_parent" android:gravity="center" android:background="#FFFF" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:id="#+id/LinearLayout02"><ImageView android:src="#drawable/iphone_vocabulary_logo_15" android:id="#+id/logoImageView" android:layout_height="wrap_content" android:layout_width="wrap_content"></ImageView>
</LinearLayout>
<LinearLayout android:layout_height="fill_parent" android:layout_width="fill_parent" android:id="#+id/wordScriptLinearLayout" android:gravity="top|center_horizontal" android:layout_below="#+id/partsOfSpeechTextView2" android:layout_above="#+id/LinearLayout02"><TextView android:layout_height="wrap_content" android:layout_margin="10dip" android:id="#+id/wordScriptTextView" android:layout_width="fill_parent" android:textColor="#F000" android:textSize="15sp"></TextView>
</LinearLayout>
</RelativeLayout>
</FrameLayout>
In the main screen when the user clicks the showScriptButton (right button of the footer), then framelayout's one relative layout switches with the another. The switching of the relative layout is shown with a flip animation.
Now, there is a text view in the middle of the footer. If we change the text of that text view from code then the flip animation doesn't work even though the frame layout doesn't change the relative layouts.
This is the setOnItemSelectedListener method for the Gallery:
wordsGallery.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int position, long arg3) {
durationTextView.setText("");
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
}
});
Here is the method for playButton:
private void playAudio() {
if(isPaused) {
myRefreshThread = new Thread(new secondCountDownRunner());
myRefreshThread.start();
audioPlayer.start();
} else {
audioPlayer = MediaPlayer.create(this, ApplicationCache.wordAudioList.get(word.wordText));
audioPlayer.setOnCompletionListener(this);
int totalDuration = audioPlayer.getDuration()/1000;
String durationText = "";
int min = totalDuration/60;
int seconds = totalDuration % 60;
if(min < 10)
durationText = "0";
durationText += min+":";
if(seconds < 10)
durationText += "0";
durationText += seconds;
System.out.println("Duration of audio:"+durationText);
durationTextView.setText(durationText);
myRefreshThread = new Thread(new secondCountDownRunner());
myRefreshThread.start();
audioPlayer.start();
}
isPaused = false;
isPlaying = true;
playButton.setBackgroundResource(R.drawable.pause_button);
}
And here is the secondCountDownRunner thread:
class secondCountDownRunner implements Runnable{
// #Override
public void run() {
while(!Thread.currentThread().isInterrupted()){
Message m = new Message();
m.what = 2;
audioPlayerHandler.sendMessage(m);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
and here is the audioPlayerHandler:
audioPlayerHandler = new Handler() {
#Override
public void handleMessage( Message msg )
{
if(msg.what == 1) {
if(isPlaying) {
if(wordsGallery.getSelectedItemPosition() < (ApplicationCache.dontKnowWords.size() - 1)) {
//currentPosition++;
//currentGalleryPosition++;
//isWordScriptShowing = false;
//updateWordDetails();
word = wordsList.get(wordsGallery.getSelectedItemPosition() + 1);
wordsGallery.setSelection(wordsGallery.getSelectedItemPosition() + 1, true);
playAudio();
}
}
} else if(msg.what == 2) {
if(isPlaying) {
int duration = audioPlayer.getDuration()/1000;
int currentPosition = audioPlayer.getCurrentPosition()/1000;
int timeLeft = duration - currentPosition;
if(timeLeft < 0)
timeLeft = 0;
String durationText = "";
int min = timeLeft/60;
int seconds = timeLeft % 60;
if(min < 10)
durationText = "0";
durationText += min+":";
if(seconds < 10)
durationText += "0";
durationText += seconds;
durationTextView.setText(durationText);
}
}
}
};
Here is the method which is called when showScriptButton is clicked:
public void flipView(int position) {
applyRotation(0, 90, position);
isFrontShowing[position] = !isFrontShowing[position];
}
private void applyRotation(float start, float end, int position) {
// Find the center of image
final float centerX, centerY;
if(isFrontShowing[position] == true) {
centerX = detailsLayout[position].getMeasuredWidth() / 2.0f;
centerY = detailsLayout[position].getMeasuredHeight() / 2.0f;
} else {
centerX = scriptLayout[position].getMeasuredWidth() / 2.0f;
centerY = scriptLayout[position].getMeasuredHeight() / 2.0f;
}
//System.out.println("center X:"+centerX+",Y:"+centerY);
// Create a new 3D rotation with the supplied parameter
// The animation listener is used to trigger the next animation
final Flip3dAnimation rotation =
new Flip3dAnimation(start, end, centerX, centerY);
rotation.setDuration(500);
rotation.setFillAfter(true);
rotation.setInterpolator(new AccelerateInterpolator());
rotation.setAnimationListener(new DisplayNextView(isFrontShowing[position], detailsLayout[position], scriptLayout[position]));
if (isFrontShowing[position] == true)
{
//detailsLayout[position].requestFocus();
//detailsLayout[position].bringToFront();
detailsLayout[position].startAnimation(rotation);
} else {
//System.out.println("---Backward flipping started...");
//scriptLayout[position].requestFocus();
//scriptLayout[position].bringToFront();
scriptLayout[position].startAnimation(rotation);
}
}
Here is the Flip3dAnimation class:
import android.graphics.Camera;
import android.graphics.Matrix;
import android.view.animation.Animation;
import android.view.animation.Transformation;
public class Flip3dAnimation extends Animation {
private final float mFromDegrees;
private final float mToDegrees;
private final float mCenterX;
private final float mCenterY;
private Camera mCamera;
public Flip3dAnimation(float fromDegrees, float toDegrees, float centerX,
float centerY) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mCenterX = centerX;
mCenterY = centerY;
}
#Override
public void initialize(int width, int height, int parentWidth,
int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mCamera = new Camera();
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final float fromDegrees = mFromDegrees;
float degrees = fromDegrees
+ ((mToDegrees - fromDegrees) * interpolatedTime);
final float centerX = mCenterX;
final float centerY = mCenterY;
final Camera camera = mCamera;
final Matrix matrix = t.getMatrix();
camera.save();
camera.rotateY(degrees);
camera.getMatrix(matrix);
camera.restore();
matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);
}
}
DisplayNextView class:
import android.view.animation.Animation;
import android.widget.RelativeLayout;
public final class DisplayNextView implements Animation.AnimationListener {
private boolean mCurrentView;
RelativeLayout layout1;
RelativeLayout layout2;
public DisplayNextView(boolean currentView, RelativeLayout layout1,
RelativeLayout layout2) {
mCurrentView = currentView;
this.layout1 = layout1;
this.layout2 = layout2;
}
public void onAnimationStart(Animation animation) {
}
public void onAnimationEnd(Animation animation) {
layout1.post(new SwapViews(mCurrentView, layout1, layout2));
}
public void onAnimationRepeat(Animation animation) {
}
}
SwapViews class:
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Animation.AnimationListener;
import android.widget.RelativeLayout;
public final class SwapViews implements Runnable {
private boolean mIsFirstView;
RelativeLayout layout1;
RelativeLayout layout2;
public SwapViews(boolean isFirstView, RelativeLayout layout1, RelativeLayout layout2) {
mIsFirstView = isFirstView;
this.layout1 = layout1;
this.layout2 = layout2;
}
public void run() {
final float centerX, centerY;
if(mIsFirstView) {
centerX = layout1.getWidth() / 2.0f;
centerY = layout1.getHeight() / 2.0f;
} else {
centerX = layout2.getWidth() / 2.0f;
centerY = layout2.getHeight() / 2.0f;
}
Flip3dAnimation rotation;
if (mIsFirstView == true) {
layout1.setVisibility(View.GONE);
layout2.setVisibility(View.VISIBLE);
layout2.requestFocus();
layout2.bringToFront();
rotation = new Flip3dAnimation(-90, 0, centerX, centerY);
} else {
layout2.setVisibility(View.GONE);
layout1.setVisibility(View.VISIBLE);
layout1.requestFocus();
layout1.bringToFront();
rotation = new Flip3dAnimation(-90, 0, centerX, centerY);
}
rotation.setDuration(500);
rotation.setFillAfter(true);
rotation.setInterpolator(new DecelerateInterpolator());
rotation.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation arg0) {
}
#Override
public void onAnimationRepeat(Animation arg0) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationEnd(Animation arg0) {
WordDetailItemAdapter.notifyAdapter();
}
});
if (mIsFirstView == true) {
layout2.startAnimation(rotation);
} else {
layout1.startAnimation(rotation);
}
}
}
Does anyone have some idea about the problem. Please help.
In your main layout, why have you got RelativeLayout04 as the sole child of the top-level LinearLayout? I think your layout's complexity might have a bearing on this issue, so am here offering a simpler alternative which uses android:layout_weight to make the Gallery fill the space not used by header or footer. Let me know if this helps.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#0000"
>
<!-- Header -->
<RelativeLayout
android:id="#+id/headerRelativeLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
...
</RelativeLayout>
<!-- The gallery -->
<Gallery
android:id="#+id/wordsGallery"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_weight="1"
...
/>
<!-- Footer -->
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="35dip"
android:background="#FF212121"
android:layout_alignParentBottom="true"
>
...
</RelativeLayout>
</LinearLayout>