i want to create one screen for my android application in this application i want to create sliding navigation feature which is full visible on swipe (Left to Right ) and when user again swipe (RIght to Left ) it again swipe and close navigation window half and display half screen , i have used navigation drawer but i am not aware with this so please some help me if you have any code so please send me its will be my pleasure .
i am sending one image for reference where .
Find below code create a class AnimationLayout
import usb.terminal.R;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
public class AnimationLayout extends ViewGroup {
public final static int DURATION = 1000;
protected boolean mPlaceLeft = true;
public boolean mOpened;
protected View mSidebar;
protected View mContent;
protected int mSidebarWidth = 100; /*
* assign default value. It will be
* overwrite in onMeasure by Layout xml
* resource.
*/
protected Animation mAnimation;
protected OpenListener mOpenListener;
protected CloseListener mCloseListener;
protected Listener mListener;
protected boolean mPressed = false;
public AnimationLayout(Context context) {
this(context, null);
}
public AnimationLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public void onFinishInflate() {
super.onFinishInflate();
mSidebar = findViewById(R.id.animation_layout_sidebar);
mContent = findViewById(R.id.animation_layout_content);
if (mSidebar == null) {
throw new NullPointerException("no view id = animation_sidebar");
}
if (mContent == null) {
throw new NullPointerException("no view id = animation_content");
}
mOpenListener = new OpenListener(mSidebar, mContent);
mCloseListener = new CloseListener(mSidebar, mContent);
}
#Override
public void onLayout(boolean changed, int l, int t, int r, int b) {
/* the title bar assign top padding, drop it */
int sidebarLeft = l;
if (!mPlaceLeft) {
sidebarLeft = r - mSidebarWidth;
}
mSidebar.layout(sidebarLeft, 0, sidebarLeft + mSidebarWidth,
0 + mSidebar.getMeasuredHeight());
if (mOpened) {
if (mPlaceLeft) {
mContent.layout(l + mSidebarWidth, 0, r + mSidebarWidth, b);
} else {
mContent.layout(l - mSidebarWidth, 0, r - mSidebarWidth, b);
}
} else {
mContent.layout(l, 0, r, b);
}
}
#Override
public void onMeasure(int w, int h) {
super.onMeasure(w, h);
super.measureChildren(w, h);
mSidebarWidth = mSidebar.getMeasuredWidth();
}
#Override
protected void measureChild(View child, int parentWSpec, int parentHSpec) {
/* the max width of Sidebar is 90% of Parent */
if (child == mSidebar) {
int mode = MeasureSpec.getMode(parentWSpec);
int width = (int) (getMeasuredWidth() * 0.9);
super.measureChild(child, MeasureSpec.makeMeasureSpec(width, mode),
parentHSpec);
} else {
super.measureChild(child, parentWSpec, parentHSpec);
}
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (!isOpening()) {
return false;
}
int action = ev.getAction();
if (action != MotionEvent.ACTION_UP
&& action != MotionEvent.ACTION_DOWN) {
return false;
}
/*
* if user press and release both on Content while sidebar is opening,
* call listener. otherwise, pass the event to child.
*/
int x = (int) ev.getX();
int y = (int) ev.getY();
if (mContent.getLeft() < x && mContent.getRight() > x
&& mContent.getTop() < y && mContent.getBottom() > y) {
if (action == MotionEvent.ACTION_DOWN) {
mPressed = true;
}
if (mPressed && action == MotionEvent.ACTION_UP
&& mListener != null) {
mPressed = false;
return mListener.onContentTouchedWhenOpening();
}
} else {
mPressed = false;
}
return false;
}
public void setListener(Listener l) {
mListener = l;
}
/* to see if the Sidebar is visible */
public boolean isOpening() {
return mOpened;
}
public void toggleSidebar() {
if (mContent.getAnimation() != null) {
return;
}
if (mOpened) {
/* opened, make close animation */
if (mPlaceLeft) {
mAnimation = new TranslateAnimation(0, -mSidebarWidth, 0, 0);
} else {
mAnimation = new TranslateAnimation(0, mSidebarWidth, 0, 0);
}
mAnimation.setAnimationListener(mCloseListener);
} else {
/* not opened, make open animation */
if (mPlaceLeft) {
mAnimation = new TranslateAnimation(0, mSidebarWidth, 0, 0);
} else {
mAnimation = new TranslateAnimation(0, -mSidebarWidth, 0, 0);
}
mAnimation.setAnimationListener(mOpenListener);
}
mAnimation.setDuration(DURATION);
mAnimation.setFillAfter(true);
mAnimation.setFillEnabled(true);
mContent.startAnimation(mAnimation);
}
public void openSidebar() {
if (!mOpened) {
toggleSidebar();
}
}
public void closeSidebar() {
if (mOpened) {
toggleSidebar();
}
}
class OpenListener implements Animation.AnimationListener {
View iSidebar;
View iContent;
OpenListener(View sidebar, View content) {
iSidebar = sidebar;
iContent = content;
}
public void onAnimationRepeat(Animation animation) {
}
public void onAnimationStart(Animation animation) {
iSidebar.setVisibility(View.VISIBLE);
}
public void onAnimationEnd(Animation animation) {
iContent.clearAnimation();
mOpened = !mOpened;
requestLayout();
if (mListener != null) {
mListener.onSidebarOpened();
}
}
}
class CloseListener implements Animation.AnimationListener {
View iSidebar;
View iContent;
CloseListener(View sidebar, View content) {
iSidebar = sidebar;
iContent = content;
}
public void onAnimationRepeat(Animation animation) {
}
public void onAnimationStart(Animation animation) {
}
public void onAnimationEnd(Animation animation) {
iContent.clearAnimation();
iSidebar.setVisibility(View.INVISIBLE);
mOpened = !mOpened;
requestLayout();
if (mListener != null) {
mListener.onSidebarClosed();
}
}
}
public interface Listener {
public void onSidebarOpened();
public void onSidebarClosed();
public boolean onContentTouchedWhenOpening();
}
}
create a mainlayout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<yourpackage..AnimationLayout
android:id="#+id/animation_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!--Create you Layout which you want and just call in this include-->
<include
android:id="#id/animation_layout_sidebar"
android:layout_width="470dp"
android:layout_height="match_parent"
layout="#layout/my_cook_menu"
android:orientation="vertical" >
</include>
<!--Create you Layout which you want and just call in this include-->
<include
android:id="#id/animation_layout_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
layout="#layout/sound_my_cook"
android:clickable="true"
android:focusable="true"
android:orientation="vertical" >
</include>
</yourpackage.AnimationLayout>
</RelativeLayout>
</RelativeLayout>
create id.xml in values folder
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item type="id" name="animation_layout_sidebar" />
<item type="id" name="animation_layout_content" />
</resources>
write this code in which activity you are calling
public class MainActivity extends Activity implements
AnimationLayout.Listener, OnClickListener{
AnimationDrawable frameAnimation;
AnimationLayout animationLayout;
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.mainlayout);
}
public void onClick(View v) {
try {
animationLayout = (AnimationLayout) findViewById(R.id.animation_layout);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
animationLayout.toggleSidebar();
}
#Override
public void onSidebarOpened() {
// TODO Auto-generated method stub
}
#Override
public void onSidebarClosed() {
// TODO Auto-generated method stub
}
#Override
public boolean onContentTouchedWhenOpening() {
// TODO Auto-generated method stub
return false;
}
}
I haven't tried it yet but I think DrawerLayout recently added to support library could give you what you need. Here is the link for documentation. This is something what Facebook app is using to slide a pannel from left to right. Here is the tutorial.
Related
I have a trapezoid shape created in custom view using below code.
#Override
protected void onDraw(Canvas canvas) {
trapezoidPath.moveTo(0,0);
trapezoidPath.lineTo(getWidth() ,0);
trapezoidPath.lineTo(getWidth() , altitude);
trapezoidPath.lineTo(0,getHeight());
trapezoidPath.lineTo(0,0);
trapezoidPath.close();
canvas.drawPath(trapezoidPath,paintTrapezoid);
}
The drawn shape looks like this.
I want to move (0,height) point to top until trapezoid shape become a rectangle. After that I want to move bottom line up until shape become a line.
Is there any way to access created path lines and it's point and manipulate them to achieve what I want ? If not how can I achieve this ?
I have to animate this shape base on user response. Thank you.
Use an ObjectAnimator to change the variables you use in onDraw. Below is an example of how you could implement this.
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TrapezoidView trapezoidView = findViewById(R.id.trapezoid);
final Button resetButton = findViewById(R.id.btn_reset);
resetButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
trapezoidView.reset();
}
});
final Button animateButton = findViewById(R.id.btn_animate);
animateButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
animateButton.setEnabled(false);
resetButton.setEnabled(false);
trapezoidView.toNewState();
}
});
trapezoidView.setListener(new TrapezoidView.TrapezoidListener() {
#Override
public void onNewState() {
animateButton.setEnabled(true);
resetButton.setEnabled(true);
}
});
}
}
TrapezoidView.java
public class TrapezoidView extends View {
public interface TrapezoidListener {
void onNewState();
}
public static final int TRAPEZOID_STATE = 0;
public static final int RECTANGLE_STATE = 1;
public static final int LINE_STATE = 2;
private int mState = TRAPEZOID_STATE;
private Paint mTrapezoidPaint;
private Path mTrapezoidPath = new Path();
private int mAnimationDuration = 5000; // 5 s in millis
private float mRectangleHeight = dpTopx(200);
private float mAltitude = mRectangleHeight;
private TrapezoidListener mListener;
public TrapezoidView(Context context, AttributeSet attrs) {
super(context, attrs);
mTrapezoidPaint = new Paint();
mTrapezoidPaint.setColor(Color.BLACK);
mTrapezoidPaint.setStrokeWidth(5.0f);
mTrapezoidPaint.setStyle(Paint.Style.STROKE);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mTrapezoidPath.reset();
if (mState == TRAPEZOID_STATE) {
mAltitude = getHeight();
}
mTrapezoidPath.moveTo(0, 0);
mTrapezoidPath.lineTo(getWidth(), 0);
if (mState == LINE_STATE) {
mTrapezoidPath.lineTo(getWidth(), mAltitude);
mTrapezoidPath.lineTo(0, mAltitude);
} else {
mTrapezoidPath.lineTo(getWidth(), mRectangleHeight);
mTrapezoidPath.lineTo(0, mAltitude);
}
mTrapezoidPath.lineTo(0, 0);
mTrapezoidPath.close();
canvas.drawPath(mTrapezoidPath, mTrapezoidPaint);
}
private float dpTopx(int dp) {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics());
}
public float getAltitude() {
return mAltitude;
}
public void setAltitude(float altitude) {
this.mAltitude = altitude;
invalidate();
}
public void reset() {
mState = TRAPEZOID_STATE;
mRectangleHeight = dpTopx(200);
mAltitude = mRectangleHeight;
invalidate();
}
public void setListener(TrapezoidListener listener) {
mListener = listener;
}
public void toNewState() {
if (mState == LINE_STATE) {
mListener.onNewState();
return;
}
float start;
float target;
final int targetState = mState == TRAPEZOID_STATE ? RECTANGLE_STATE : LINE_STATE;
if (targetState == RECTANGLE_STATE) {
start = getHeight();
target = mRectangleHeight;
} else {
start = mAltitude;
target = 0.0f;
}
ObjectAnimator stateAnimation = ObjectAnimator.ofFloat(TrapezoidView.this, "Altitude", start);
stateAnimation.setFloatValues(target);
stateAnimation.setDuration(mAnimationDuration);
stateAnimation.addListener(
new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
mState = targetState;
}
#Override
public void onAnimationEnd(Animator animation) {
mListener.onNewState();
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
}
);
stateAnimation.start();
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="50dp"
tools:context="test.example.MainActivity">
<test.example.TrapezoidView
android:id="#+id/trapezoid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.9" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.1"
android:orientation="horizontal">
<Button
android:id="#+id/btn_animate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Animate!" />
<Button
android:id="#+id/btn_reset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Reset" />
</LinearLayout>
</LinearLayout>
I have to build animation like This.
Sorry I don't have too much reputation to upload image. you can find gif file from the above link.
I have done all this and it works fine on KitKat and LollyPop only but not on the other API version. I am using this library. Can any one please figure out the actual problem
Here is my code. Thanks in advance
public abstract class AbstractSlideExpandableListAdapter extends WrapperListAdapterImpl
{
private View lastOpnUpperView = null;
ArrayList<View> upperViewsList = new ArrayList<View>();
ArrayList<View> lowerViewsList = new ArrayList<View>();
ArrayList<View> circleViewsList = new ArrayList<View>();
private View lastOpen = null;
private int lastOpenPosition = -1;
private int lastOpenItemIndex = 0;
private int animationDuration = 800;
private BitSet openItems = new BitSet();
private final SparseIntArray viewHeights = new SparseIntArray(10);
private ViewGroup parent;
public AbstractSlideExpandableListAdapter(ListAdapter wrapped)
{
super(wrapped);
lastOpenPosition = 0;
openItems.set(lastOpenPosition, true);
}
private OnItemExpandCollapseListener expandCollapseListener;
public void setItemExpandCollapseListener(OnItemExpandCollapseListener listener)
{
expandCollapseListener = listener;
}
public void removeItemExpandCollapseListener()
{
expandCollapseListener = null;
}
public interface OnItemExpandCollapseListener
{
public void onExpand(View itemView, int position);
public void onCollapse(View itemView, int position);
}
private void notifiyExpandCollapseListener(int type, View view, int position)
{
if (expandCollapseListener != null)
{
if (type == ExpandCollapseAnimation.EXPAND)
{
expandCollapseListener.onExpand(view, position);
}
else if (type == ExpandCollapseAnimation.COLLAPSE)
{
expandCollapseListener.onCollapse(view, position);
}
}
}
#Override
public View getView(int position, View view, ViewGroup viewGroup)
{
this.parent = viewGroup;
view = wrapped.getView(position, view, viewGroup);
enableFor(view, position);
return view;
}
public abstract View getExpandToggleButton(View parent);
public abstract View getExpandableView(View parent);
// upperView to expand animation for sequeeze
public abstract View getUpperView(View upperView);
// Lower view to expand and collapse
public abstract View getLowerView(View upperView);
// Get the circle view to hide and show
public abstract View getCircleView(View circleView);
/**
* Gets the duration of the collapse animation in ms. Default is 330ms. Override this method to change the default.
*
* #return the duration of the anim in ms
*/
public int getAnimationDuration()
{
return animationDuration;
}
/**
* Set's the Animation duration for the Expandable animation
*
* #param duration
* The duration as an integer in MS (duration > 0)
* #exception IllegalArgumentException
* if parameter is less than zero
*/
public void setAnimationDuration(int duration)
{
if (duration < 0)
{
throw new IllegalArgumentException("Duration is less than zero");
}
animationDuration = duration;
}
/**
* Check's if any position is currently Expanded To collapse the open item #see collapseLastOpen
*
* #return boolean True if there is currently an item expanded, otherwise false
*/
public boolean isAnyItemExpanded()
{
return (lastOpenPosition != -1) ? true : false;
}
public void enableFor(View parent, int position)
{
View more = getExpandToggleButton(parent);
View itemToolbar = getExpandableView(parent);
View upperView = getUpperView(parent);
View circleView = getCircleView(parent);
View lowerView = getLowerView(parent);
itemToolbar.measure(parent.getWidth(), parent.getHeight());
upperViewsList.add(upperView);
circleViewsList.add(circleView);
lowerViewsList.add(lowerView);
if (position == 0)
{
// lastopenUpperViewTemporary = upperView;
lastOpnUpperView = upperView;
upperView.setVisibility(View.GONE);
lowerView.setVisibility(View.GONE);
}
enableFor(more, upperView, itemToolbar, position);
itemToolbar.requestLayout();
}
private void animateListExpand(final View button, final View target, final int position)
{
target.setAnimation(null);
int type;
if (target.getVisibility() == View.VISIBLE)
{
type = ExpandCollapseAnimation.COLLAPSE;
}
else
{
type = ExpandCollapseAnimation.EXPAND;
}
// remember the state
if (type == ExpandCollapseAnimation.EXPAND)
{
openItems.set(position, true);
}
else
{
openItems.set(position, false);
}
// check if we need to collapse a different view
if (type == ExpandCollapseAnimation.EXPAND)
{
if (lastOpenPosition != -1 && lastOpenPosition != position)
{
if (lastOpen != null)
{
animateWithUpperView(lastOpen, ExpandCollapseAnimation.COLLAPSE, position);
// animateView(lastOpen, ExpandCollapseAnimation.COLLAPSE);
notifiyExpandCollapseListener(ExpandCollapseAnimation.COLLAPSE, lastOpen, lastOpenPosition);
}
openItems.set(lastOpenPosition, false);
}
lastOpen = target;
lastOpenPosition = position;
}
else if (lastOpenPosition == position)
{
lastOpenPosition = -1;
}
// animateView(target, type);
// Expand the view which was collapse
Animation anim = new ExpandCollapseAnimation(target, type);
anim.setDuration(getAnimationDuration());
target.startAnimation(anim);
this.notifiyExpandCollapseListener(type, target, position);
// }
}
private void enableFor(final View button, final View upperView, final View target, final int position)
{
// lastopenUpperViewTemporary = upperView;
if (target == lastOpen && position != lastOpenPosition)
{
// lastOpen is recycled, so its reference is false
lastOpen = null;
}
if (position == lastOpenPosition)
{
// re reference to the last view
// so when can animate it when collapsed
// lastOpen = target;
lastOpen = target;
lastOpnUpperView = upperView;
}
int height = viewHeights.get(position, -1);
if (height == -1)
{
viewHeights.put(position, target.getMeasuredHeight());
updateExpandable(target, position);
}
else
{
updateExpandable(target, position);
}
button.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(final View view)
{
System.out.println("Position: " + position);
if (lastOpenPosition == position)
{
return;
}
System.out.println("Upper View: " + upperView);
Animation anim = new ExpandCollapseUpperViewAnimation(upperViewsList.get(position), ExpandCollapseUpperViewAnimation.COLLAPSE);
anim.setDuration(800);
anim.setAnimationListener(new AnimationListener()
{
#Override
public void onAnimationStart(Animation animation)
{
circleViewsList.get(position).setVisibility(View.GONE);
}
#Override
public void onAnimationRepeat(Animation animation)
{
// TODO Auto-generated method stub
}
#Override
public void onAnimationEnd(Animation animation)
{
// TODO Auto-generated method stub
// upperViewsList.get(position).setVisibility(View.VISIBLE);
animateListExpand(button, target, position);
}
});
upperViewsList.get(position).startAnimation(anim);
// Lower animation
Animation lowerAnim = new ExpandCollapseUpperViewAnimation(lowerViewsList.get(position), ExpandCollapseUpperViewAnimation.COLLAPSE);
lowerAnim.setDuration(800);
lowerViewsList.get(position).startAnimation(lowerAnim);
}
});
}
private void updateExpandable(View target, int position)
{
final LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) target.getLayoutParams();
if (openItems.get(position))
{
target.setVisibility(View.VISIBLE);
params.bottomMargin = 0;
}
else
{
target.setVisibility(View.GONE);
params.bottomMargin = 0 - viewHeights.get(position);
}
}
/**
* Performs either COLLAPSE or EXPAND animation on the target view
*
* #param target
* the view to animate
* #param type
* the animation type, either ExpandCollapseAnimation.COLLAPSE or ExpandCollapseAnimation.EXPAND
*/
private void animateView(final View target, final int type)
{
Animation anim = new ExpandCollapseAnimation(target, type);
anim.setDuration(getAnimationDuration());
anim.setAnimationListener(new AnimationListener()
{
#Override
public void onAnimationStart(Animation animation)
{
}
#Override
public void onAnimationRepeat(Animation animation)
{
}
#Override
public void onAnimationEnd(Animation animation)
{
System.out.println("Animation End");
if (type == ExpandCollapseAnimation.EXPAND)
{
if (parent instanceof ListView)
{
ListView listView = (ListView) parent;
int movement = target.getBottom();
Rect r = new Rect();
boolean visible = target.getGlobalVisibleRect(r);
Rect r2 = new Rect();
listView.getGlobalVisibleRect(r2);
if (!visible)
{
listView.smoothScrollBy(movement, getAnimationDuration());
}
else
{
if (r2.bottom == r.bottom)
{
listView.smoothScrollBy(movement, getAnimationDuration());
}
}
}
}
}
});
target.startAnimation(anim);
}
private void animateWithUpperView(final View target, final int type, final int position)
{
Animation anim = new ExpandCollapseAnimation(target, type);
anim.setDuration(getAnimationDuration());
anim.setAnimationListener(new AnimationListener()
{
#Override
public void onAnimationStart(Animation animation)
{
}
#Override
public void onAnimationRepeat(Animation animation)
{
}
#Override
public void onAnimationEnd(Animation animation)
{
// upperViewsList.get(lastOpenItemForUpperView).setVisibility(View.VISIBLE);
// lastOpenItemForUpperView = position;
Animation expandItemAniamtion = new ExpandCollapseLowerViewAnimation(upperViewsList.get(lastOpenItemIndex), ExpandCollapseUpperViewAnimation.EXPAND);
expandItemAniamtion.setDuration(800);
expandItemAniamtion.setAnimationListener(new AnimationListener()
{
#Override
public void onAnimationStart(Animation animation)
{
}
#Override
public void onAnimationRepeat(Animation animation)
{
// TODO Auto-generated method stub
}
#Override
public void onAnimationEnd(Animation animation)
{
circleViewsList.get(lastOpenItemIndex).setVisibility(View.VISIBLE);
lastOpenItemIndex = position;
}
});
// Lower view animation
Animation lowerAnim = new ExpandCollapseLowerViewAnimation(lowerViewsList.get(lastOpenItemIndex), ExpandCollapseUpperViewAnimation.EXPAND);
lowerAnim.setDuration(800);
upperViewsList.get(lastOpenItemIndex).startAnimation(expandItemAniamtion);
lowerViewsList.get(lastOpenItemIndex).startAnimation(lowerAnim);
}
});
target.startAnimation(anim);
}
/**
* Closes the current open item. If it is current visible it will be closed with an animation.
*
* #return true if an item was closed, false otherwise
*/
public boolean collapseLastOpen()
{
if (isAnyItemExpanded())
{
// if visible animate it out
if (lastOpen != null)
{
animateView(lastOpen, ExpandCollapseAnimation.COLLAPSE);
}
openItems.set(lastOpenPosition, false);
lastOpenPosition = -1;
return true;
}
return false;
}
public Parcelable onSaveInstanceState(Parcelable parcelable)
{
SavedState ss = new SavedState(parcelable);
ss.lastOpenPosition = this.lastOpenPosition;
ss.openItems = this.openItems;
return ss;
}
public void onRestoreInstanceState(SavedState state)
{
if (state != null)
{
this.lastOpenPosition = state.lastOpenPosition;
this.openItems = state.openItems;
}
}
/**
* Utility methods to read and write a bitset from and to a Parcel
*/
private static BitSet readBitSet(Parcel src)
{
BitSet set = new BitSet();
if (src == null)
{
return set;
}
int cardinality = src.readInt();
for (int i = 0; i < cardinality; i++)
{
set.set(src.readInt());
}
return set;
}
private static void writeBitSet(Parcel dest, BitSet set)
{
int nextSetBit = -1;
if (dest == null || set == null)
{
return; // at least dont crash
}
dest.writeInt(set.cardinality());
while ((nextSetBit = set.nextSetBit(nextSetBit + 1)) != -1)
{
dest.writeInt(nextSetBit);
}
}
/**
* The actual state class
*/
static class SavedState extends View.BaseSavedState
{
public BitSet openItems = null;
public int lastOpenPosition = -1;
SavedState(Parcelable superState)
{
super(superState);
}
private SavedState(Parcel in)
{
super(in);
lastOpenPosition = in.readInt();
openItems = readBitSet(in);
}
#Override
public void writeToParcel(Parcel out, int flags)
{
super.writeToParcel(out, flags);
out.writeInt(lastOpenPosition);
writeBitSet(out, openItems);
}
// required field that makes Parcelables from a Parcel
public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>()
{
public SavedState createFromParcel(Parcel in)
{
return new SavedState(in);
}
public SavedState[] newArray(int size)
{
return new SavedState[size];
}
};
}
public static Animation ExpandOrCollapseView(final View v, final boolean expand)
{
try
{
Method m = v.getClass().getDeclaredMethod("onMeasure", int.class, int.class);
m.setAccessible(true);
m.invoke(v, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(((View) v.getParent()).getMeasuredWidth(), MeasureSpec.AT_MOST));
}
catch (Exception e)
{
e.printStackTrace();
}
final int initialHeight = v.getMeasuredHeight();
if (expand)
{
v.getLayoutParams().height = 0;
}
else
{
v.getLayoutParams().height = initialHeight;
}
v.setVisibility(View.VISIBLE);
Animation a = new Animation()
{
#Override
protected void applyTransformation(float interpolatedTime, Transformation t)
{
int newHeight = 0;
if (expand)
{
newHeight = (int) (initialHeight * interpolatedTime);
}
else
{
newHeight = (int) (initialHeight * (1 - interpolatedTime));
}
v.getLayoutParams().height = newHeight;
v.requestLayout();
if (interpolatedTime == 1 && !expand)
v.setVisibility(View.GONE);
}
#Override
public boolean willChangeBounds()
{
return true;
}
};
a.setDuration(1000);
return a;
}}
Luckily I have found the solution. On pre-kitkat the upperView on list item which was gone does not forcelly animate but on kitkat and so on it forcelly animate from gone to visible.
So as the solution we must give a layer of view between of list item and upper view (Which we have to animate).
In this way it will work like charm.
I want develope this rotation in my App . I have implemented the "down" menu ("můj dealer", "moje Volvo", "kontakty") and I need implement the "upper" rotating menu.
How can I do it? Do you have tips? Hope you understand me.
Images (please, watch the video above in the link):
Menu_item_test.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/menuItemImg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:src="#drawable/tab_1_1" />
</RelativeLayout>
Activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/rotationMenu" >
</FrameLayout>
<ImageView
android:id="#+id/imageViewShadow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="60dp"
android:contentDescription="shadow"
android:scaleType="fitXY"
android:src="#drawable/half_round_back" />
<cz.mixedapps.volvista.RotationMenu
android:id="#+id/rotationMenu"
android:layout_width="match_parent"
android:layout_height="265dp"
android:layout_alignParentBottom="true" >
</cz.mixedapps.volvista.RotationMenu>
</RelativeLayout>
I have put together a custom view which replicates the behaviour, you still have to style it like in you example, but it works with an arbitrary number of child views and currently looks like this:
EDIT: I added the ability to show and hide the upper rotating menu with two methods, showRotationMenu() and hideRotationMenu():
Of course there is a lot you can do to improve this view. I just wrote this in 15 minutes and therefor it is a little rough around the edges. But it should be more than enough to put you on the right track. Both the looks of the buttons and of the views which rotate is completely customisable.
1) Source
RotationMenu.java:
import android.content.Context;
import android.content.res.Resources;
import android.database.DataSetObserver;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.*;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
/**
* Created by Xaver Kapeller on 26/03/14.
*/
public class RotationMenu extends LinearLayout {
private final DataSetObserver dataSetObserver = new DataSetObserver() {
#Override
public void onChanged() {
super.onChanged();
reloadAdapter();
}
};
private RotationMenuAdapter adapter;
private FrameLayout flViewContainer;
private LinearLayout llMenu;
private View currentView;
private View previousView;
private int animationPivotX;
private int animationPivotY;
private int selectedPosition = 0;
public RotationMenu(Context context) {
super(context);
setupMenu();
}
public RotationMenu(Context context, AttributeSet attrs) {
super(context, attrs);
setupMenu();
}
public RotationMenu(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setupMenu();
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
this.animationPivotX = w / 2;
this.animationPivotY = h;
}
private void setupMenu() {
this.setOrientation(VERTICAL);
this.flViewContainer = new FrameLayout(getContext());
this.addView(this.flViewContainer, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dpToPixel(150)));
this.llMenu = new LinearLayout(getContext());
this.llMenu.setOrientation(LinearLayout.HORIZONTAL);
this.addView(this.llMenu, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
}
private int dpToPixel(int dp) {
float scale = getDisplayDensityFactor();
return (int) (dp * scale + 0.5f);
}
private float getDisplayDensityFactor() {
Resources res = getResources();
if (res != null) {
DisplayMetrics metrics = res.getDisplayMetrics();
if(metrics != null) {
return metrics.density;
}
}
return 1.0f;
}
public RotationMenuAdapter getAdapter() {
return this.adapter;
}
public void setAdapter(RotationMenuAdapter adapter) {
if (adapter != null) {
if (this.adapter != null) {
this.adapter.unregisterDataSetObserver(this.dataSetObserver);
}
adapter.registerDataSetObserver(this.dataSetObserver);
this.adapter = adapter;
reloadAdapter();
}
}
public boolean isRotationMenuVisible() {
return this.flViewContainer.getVisibility() == View.VISIBLE;
}
public void showRotationMenu() {
if(this.flViewContainer.getVisibility() != View.VISIBLE) {
this.flViewContainer.setVisibility(View.VISIBLE);
AnimationSet set = new AnimationSet(false);
TranslateAnimation translateAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1, Animation.RELATIVE_TO_SELF, 0);
translateAnimation.setDuration(1000);
set.addAnimation(translateAnimation);
AlphaAnimation alphaAnimation = new AlphaAnimation(0, 1);
alphaAnimation.setDuration(1000);
set.addAnimation(alphaAnimation);
this.flViewContainer.startAnimation(set);
}
}
public void hideRotationMenu() {
if(this.flViewContainer.getVisibility() == View.VISIBLE) {
AnimationSet set = new AnimationSet(false);
TranslateAnimation translateAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1);
translateAnimation.setDuration(1000);
set.addAnimation(translateAnimation);
AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0);
alphaAnimation.setDuration(1000);
set.addAnimation(alphaAnimation);
set.setAnimationListener(new ViewAnimationEndListener(this.flViewContainer) {
#Override
protected void onAnimationEnd(Animation animation, View view) {
view.setVisibility(View.GONE);
}
});
this.flViewContainer.startAnimation(set);
}
}
private void reloadAdapter() {
Context context = getContext();
if (this.adapter != null && context != null) {
int viewCount = this.adapter.getCount();
int oldViewCount = this.llMenu.getChildCount();
for (int i = 0; i < Math.max(oldViewCount, viewCount); i++) {
if (i < viewCount) {
LayoutParams layoutParams = new LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1);
View menuItem;
if (i < this.llMenu.getChildCount()) {
menuItem = this.adapter.getMenuItemView(i, this.llMenu.getChildAt(i), this.llMenu);
if(menuItem.getParent() == null) {
this.llMenu.removeViewAt(i);
this.llMenu.addView(menuItem, i, layoutParams);
}
} else {
menuItem = this.adapter.getMenuItemView(i, null, this.llMenu);
this.llMenu.addView(menuItem, layoutParams);
}
menuItem.setOnClickListener(new MenuItemClickListener(i));
} else {
this.llMenu.removeViewAt(i);
}
}
this.flViewContainer.removeAllViews();
this.previousView = this.currentView;
if (this.selectedPosition >= viewCount) {
this.selectedPosition = viewCount - 1;
}
this.currentView = this.adapter.getView(this.selectedPosition, this.previousView, this);
addViewWithAnimation(this.currentView, false);
}
}
public void switchToItem(int position, boolean animate) {
if (this.adapter != null) {
int viewCount = this.adapter.getCount();
position = valueInRange(position, 0, viewCount - 1);
if (position != this.selectedPosition) {
View oldView = this.currentView;
this.currentView = this.adapter.getView(position, this.previousView, this);
this.previousView = oldView;
addViewWithAnimation(this.currentView, animate, position < this.selectedPosition);
removeViewWithAnimation(this.previousView, animate, position < this.selectedPosition);
this.selectedPosition = position;
}
}
}
private int valueInRange(int value, int min, int max) {
if (value > max) {
value = max;
} else if (value < min) {
value = min;
}
return value;
}
private void addViewWithAnimation(View view, boolean animate, boolean leftToRight) {
if (view != null) {
if(view.getParent() == null) {
this.flViewContainer.addView(view, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
}
if (animate) {
int start = leftToRight ? -90 : 90;
Animation rotateIn = new RotateAnimation(start, 0, this.animationPivotX, this.animationPivotY);
rotateIn.setDuration(1000);
view.startAnimation(rotateIn);
}
}
}
private void addViewWithAnimation(View view, boolean animate) {
addViewWithAnimation(view, animate, true);
}
private void removeViewWithAnimation(View view, boolean animate, boolean leftToRight) {
if (view != null) {
if (animate) {
int target = leftToRight ? 90 : -90;
Animation rotateOut = new RotateAnimation(0, target, this.animationPivotX, this.animationPivotY);
rotateOut.setDuration(1000);
rotateOut.setAnimationListener(new ViewAnimationEndListener(view) {
#Override
protected void onAnimationEnd(Animation animation, View view) {
flViewContainer.removeView(view);
}
});
view.startAnimation(rotateOut);
} else {
this.flViewContainer.removeView(view);
}
}
}
private void removeViewWithAnimation(View view, boolean animate) {
removeViewWithAnimation(view, animate, true);
}
private abstract class ViewAnimationEndListener implements Animation.AnimationListener {
private final View view;
private ViewAnimationEndListener(View view) {
this.view = view;
}
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
onAnimationEnd(animation, this.view);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
protected abstract void onAnimationEnd(Animation animation, View view);
}
private class MenuItemClickListener implements OnClickListener {
private final int position;
MenuItemClickListener(int position) {
this.position = position;
}
#Override
public void onClick(View v) {
if(adapter != null && adapter.isMenuItemEnabled(this.position) && isRotationMenuVisible()) {
switchToItem(this.position, true);
}
}
}
}
RotationMenuAdapter.java:
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
/**
* Created by Xaver Kapeller on 26/03/14.
*/
public abstract class RotationMenuAdapter extends BaseAdapter {
public abstract View getMenuItemView(int position, View convertView, ViewGroup parent);
public abstract long getMenuItemId(int position);
public abstract boolean isMenuItemEnabled(int position);
}
2) Usage:
The custom view is making use of adapters and view recycling, so you use it the same way you would use a ListView. Because of the view recycling it is not very memory intensive and actually pretty fast. The logic for the creating of the menu items at the bottom is also in the adapter and it too uses view recycling. So be sure that you implement getMenuItemView() with the same care you would use to implement getView(). First you have to write an adapter:
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import at.test.app.R;
import at.test.app.RotationMenu.RotationMenuAdapter;
import java.util.List;
/**
* Created by Xaver Kapeller on 26/03/14.
*/
public class TestAdapter extends RotationMenuAdapter {
private static final long TEST_VIEW_ID = 0;
private static final long DEFAULT_VIEW_ID = TEST_VIEW_ID;
private static final long TEST_MENU_ID = 0;
private static final long DEFAULT_MENU_ID = TEST_MENU_ID;
private final LayoutInflater inflater;
private final List<TestViewModel> viewModels;
public TestAdapter(Context context, List<TestViewModel> viewModels) {
this.inflater = LayoutInflater.from(context);
this.viewModels = viewModels;
}
#Override
public int getCount() {
return this.viewModels.size();
}
#Override
public Object getItem(int position) {
return this.viewModels.get(position);
}
#Override
public long getItemId(int position) {
Object viewModel = getItem(position);
if(viewModel instanceof TestViewModel) {
return TEST_VIEW_ID;
}
return DEFAULT_VIEW_ID;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(getItemId(position) == TEST_VIEW_ID) {
TestViewModel viewModel = (TestViewModel) getItem(position);
TestRow row;
if(convertView == null) {
convertView = this.inflater.inflate(TestRow.LAYOUT, parent, false);
row = new TestRow(convertView);
convertView.setTag(row);
}
row = (TestRow) convertView.getTag();
row.bind(viewModel);
}
return convertView;
}
#Override
public View getMenuItemView(int position, View convertView, ViewGroup parent) {
if(getMenuItemId(position) == TEST_MENU_ID) {
TestViewModel viewModel = (TestViewModel)getItem(position);
MenuRow row;
if(convertView == null) {
convertView = this.inflater.inflate(MenuRow.LAYOUT, parent, false);
row = new MenuRow(convertView);
convertView.setTag(row);
}
row = (MenuRow)convertView.getTag();
row.bind(viewModel);
}
return convertView;
}
#Override
public long getMenuItemId(int position) {
Object item = getItem(position);
if(item instanceof TestViewModel) {
return TEST_MENU_ID;
}
return DEFAULT_MENU_ID;
}
#Override
public boolean isMenuItemEnabled(int position) {
return true;
}
}
Nothing special, except the extra methods for the creating of the menu items. In isMenuItemEnabled() you can add logic to enable/disable menu items if you need to.
And then you apply your adapter to the view:
List<TestViewModel> viewModels = new ArrayList<TestViewModel>();
TestViewModel menuItemOne = new TestViewModel();
menuItemOne.setMenuItemIconResId(R.drawable.icon);
viewModels.add(menuItemOne);
TestViewModel menuItemTwo = new TestViewModel();
menuItemTwo.setMenuItemIconResId(R.drawable.icon);
viewModels.add(menuItemTwo);
TestAdapter adapter = new TestAdapter(getActivity(), viewModels);
this.rotationMenu.setAdapter(adapter);
EDIT:
Try this layout with wrap_content instead match_parent:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:id="#+id/menuItemImg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:src="#drawable/tab_1_1" />
</RelativeLayout>
I'm also no so sure about your layout_width, are you sure you need match_parent there? I don't think so.
I am using touch listener for an imageview in the listview item .It is working fine when I just do that like an sample application(I mean I have that Listview item as an sample one). But when I put this in a listview it is really becoming very slow.
I just wants to drag the image only horizantally,for that purpose I used ConstrainedDragandDrop View class which I got from the Github.
In my sample application:
public class HorizontalScroll extends Activity {
ImageView full_left,heart;
RelativeLayout rlMainLayout,rlImages,Cartoon_image,half_left,play_btn,centre,centre_leftanimate;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.inflated_bloops);
half_left=(RelativeLayout)findViewById(R.id.half_left);
Cartoon_image=(RelativeLayout)findViewById(R.id.cartoon_image);
play_btn=(RelativeLayout)findViewById(R.id.play_btn);
heart=(ImageView)findViewById(R.id.ivheart);
ConstrainedDragAndDropView dndView = (ConstrainedDragAndDropView) findViewById(R.id.dndView);
dndView.setDragHandle(findViewById(R.id.cartoon_image),findViewById(R.id.half_left),heart);
dndView.setAllowVerticalDrag(false,HorizontalScroll.this);
}
}
When I used in my Listview:
public class Cars extends BaseAdapter
{
public View getView(int position, View convertView, ViewGroup parent)
{
View v = convertView;
LayoutInflater inflator = getLayoutInflater();
v= inflator.inflate(R.layout.inflated_bloops, null);
ConstrainedDragAndDropView dndView = (ConstrainedDragAndDropView) v.findViewById(R.id.dndView);
dndView.setDragHandle(v.findViewById(R.id.cartoon_image),v.findViewById(R.id.half_left),heart);
dndView.setAllowVerticalDrag(false,FeedModeActivity.this);
RelativeLayout Cartoon_image=(RelativeLayout)v.findViewById(R.id.cartoon_image);
ImageView ivDummy =(ImageView)v.findViewById(R.id.dummy);
try{
loader.DisplayImageRelative( al_new.get(position).replace(" ", "%20"),ivDummy, Cartoon_image);
}
catch(Exception e){
e.printStackTrace();
}
return v;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return al_new.size();
}
#Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
}
Here is my custom dragDrop view:
public class ConstrainedDragAndDropView extends LinearLayout {
Activity main;
protected View dragHandle,half,heart;
protected List<View> dropTargets = new ArrayList<View>();
protected boolean dragging = false;
protected int pointerId;
protected int selectedDropTargetIndex = -1;
protected int lastSelectedDropTargetIndex = -1;
protected int lastDroppedIndex = -1;
protected boolean allowHorizontalDrag = true;
protected boolean allowVerticalDrag = true;
protected DropListener dropListener;
public interface DropListener {
public void onDrop(final int dropIndex, final View dropTarget);
}
public ConstrainedDragAndDropView(Context context) {
super(context);
}
public ConstrainedDragAndDropView(Context context, AttributeSet attrs) {
super(context, attrs);
applyAttrs(context, attrs);
}
#SuppressLint("NewApi")
public ConstrainedDragAndDropView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
applyAttrs(context, attrs);
}
public DropListener getDropListener() {
return dropListener;
}
public void setDropListener(DropListener dropListener) {
this.dropListener = dropListener;
}
public View getDragHandle() {
return dragHandle;
}
public void setDragHandle(View dragHandle,View half_left,View heart) {
this.dragHandle = dragHandle;
this.half=half_left;
this.heart=heart;
setupDragHandle();
}
public List<View> getDropTargets() {
return dropTargets;
}
public void setDropTargets(List<View> dropTargets) {
this.dropTargets = dropTargets;
}
public void addDropTarget(View target) {
if (dropTargets == null) {
dropTargets = new ArrayList<View>();
}
dropTargets.add(target);
}
public boolean isAllowHorizontalDrag() {
return allowHorizontalDrag;
}
public void setAllowHorizontalDrag(boolean allowHorizontalDrag) {
this.allowHorizontalDrag = allowHorizontalDrag;
}
public boolean isAllowVerticalDrag() {
return allowVerticalDrag;
}
public void setAllowVerticalDrag(boolean allowVerticalDrag,Activity c) {
this.allowVerticalDrag = allowVerticalDrag;
this.main=c;
}
protected void applyAttrs(Context context, AttributeSet attrs) {
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.ConstrainedDragAndDropView, 0, 0);
try {
/*
layoutId = a.getResourceId(R.styleable.ConstrainedDragAndDropView_layoutId, 0);
if (layoutId > 0) {
LayoutInflater.from(context).inflate(layoutId, this, true);
}
*/
} finally {
a.recycle();
}
}
protected void setupDragHandle() {
this.setOnTouchListener(new DragAreaTouchListener());
}
protected class DragAreaTouchListener implements OnTouchListener {
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.d("Action down", "action down in listener");
onActionDown(view, motionEvent);
break;
case MotionEvent.ACTION_UP:
Log.d("Action up", "action up in listener");
onActionUp(view, motionEvent);
break;
case MotionEvent.ACTION_MOVE:
Log.d("Action move", "action move in listener");
onActionMove(view, motionEvent);
break;
default:
break;
}
return true;
}
}
public static int param;
protected void onActionDown(View view, MotionEvent motionEvent) {
// if we're not already dragging, and the touch position is on the drag handle,
// then start dragging
if(!dragging && isDragHandleTouch(motionEvent)) {
pointerId = motionEvent.getPointerId(0);
Float s1= dragHandle.getX();
param=Integer.valueOf(s1.intValue());
Log.e("param",""+param);
// updateDragPosition(motionEvent);
dragging = true;
Log.d("drag", "drag start");
}
}
protected void onActionUp(View view, MotionEvent motionEvent) {
Log.d("Action up", "action up");
// if we're dragging, then stop dragging
if (dragging && motionEvent.getPointerId(0) == pointerId) {
Log.e("condition","satisfied");
Log.e("x val"+(int)motionEvent.getX(),"y val"+(int)motionEvent.getY());
Log.e("x1"+half.getLeft(),"y1"+half.getTop());
Log.e("x4"+half.getRight(),"y4"+half.getBottom());
Float s1=motionEvent.getX();
Float s2=motionEvent.getY();
int x=Integer.valueOf(s1.intValue());
dragging = false;
int y=Integer.valueOf(s2.intValue());
if((half.getLeft()<x)&&(x<half.getRight())&&((half.getTop()<y)&&(y<half.getBottom())))
{
Log.e("drop","on target");
try {
Thread.sleep(1000);
dragHandle.setX(param);
heart.setVisibility(View.VISIBLE);
Animation pulse = AnimationUtils.loadAnimation(main, R.anim.pulse);
heart.startAnimation(pulse);
// heart.setVisibility(View.GONE);
pulse.setAnimationListener(new AnimationListener() {
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
Log.e("animation","start");
}
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
public void onAnimationEnd(Animation animation) {
// TODO Auto-generated method stub
Log.e("animation","end");
heart.setVisibility(View.GONE);
}
});
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// class SimpleThread extends Thread {
//
// public void run() {
//
// try {
// sleep(1000);
// runOnUiThread(new Runnable() {
// public void run() {
// dragHandle.setX(param);
// heart.setVisibility(View.VISIBLE);
//
// Animation pulse = AnimationUtils.loadAnimation(main, R.anim.pulse);
// heart.startAnimation(pulse);
// }
// });
//
// }
// catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
//
// }
// }
//
// new SimpleThread().start();
}
else{
Log.e("drop",""+"outside target");
dragHandle.setX(param);
// TranslateAnimation transAnimation= new TranslateAnimation(x, 300, y, 300);
// transAnimation.setDuration(1000);//set duration
// view.startAnimation(transAnimation);
}
// if()
// updateDragPosition(motionEvent);
Log.d("drag", "drag end");
// find out what drop target, if any, the drag handle was dropped on
int dropTargetIndex = findDropTargetIndexUnderDragHandle();
if(dropTargetIndex >= 0) { // if drop was on a target, select the target
Log.d("drag", "drop on target " + dropTargetIndex);
// selectDropTarget(dropTargetIndex);
// snapDragHandleToDropTarget(dropTargetIndex);
// lastDroppedIndex = dropTargetIndex;
if(dropListener != null) {
dropListener.onDrop(dropTargetIndex, dropTargets.get(dropTargetIndex));
}
} else { // if drop was not on a target, re-select the last selected target
// deselectDropTarget();
// snapDragHandleToDropTarget(lastDroppedIndex);
}
}
else{
Log.e("condition not","satisfied");
}
}
protected void onActionMove(View view, MotionEvent motionEvent) {
Log.d("Action move", "action move");
if (dragging && motionEvent.getPointerId(0) == pointerId) {
updateDragPosition(motionEvent);
int dropTargetIndex = findDropTargetIndexUnderDragHandle();
if(dropTargetIndex >= 0) {
Log.d("drag", "hover on target " + dropTargetIndex);
// selectDropTarget(dropTargetIndex);
} else {
// deselectDropTarget();
}
}
}
#SuppressLint("NewApi")
protected void updateDragPosition(MotionEvent motionEvent) {
// this is where we constrain the movement of the dragHandle
if(allowHorizontalDrag) {
float candidateX = motionEvent.getX() - dragHandle.getWidth() / 2;
if(candidateX > 0 && candidateX + dragHandle.getWidth() < this.getWidth()) {
dragHandle.setX(candidateX);
}
}
if(allowVerticalDrag) {
float candidateY = motionEvent.getY() - dragHandle.getHeight() / 2;
if(candidateY > 0 && candidateY + dragHandle.getHeight() < this.getHeight()) {
dragHandle.setY(candidateY);
}
}
}
#SuppressLint("NewApi")
protected void snapDragHandleToDropTarget(int dropTargetIndex) {
if(dropTargetIndex > -1) {
View dropTarget = dropTargets.get(dropTargetIndex);
float xCenter = dropTarget.getX() + dropTarget.getWidth() / 2;
float yCenter = dropTarget.getY() + dropTarget.getHeight() / 2;
float xOffset = dragHandle.getWidth() / 2;
float yOffset = dragHandle.getHeight() / 2;
float x = xCenter - xOffset;
float y = yCenter - yOffset;
dragHandle.setX(x);
dragHandle.setY(y);
}
}
protected boolean isDragHandleTouch(MotionEvent motionEvent) {
Point point = new Point(
new Float(motionEvent.getRawX()).intValue(),
new Float(motionEvent.getRawY()).intValue()
);
return isPointInView(point, dragHandle);
}
protected int findDropTargetIndexUnderDragHandle() {
int dropTargetIndex = -1;
for(int i = 0; i < dropTargets.size(); i++) {
if(isCollision(dragHandle, dropTargets.get(i))) {
dropTargetIndex = i;
break;
}
}
return dropTargetIndex;
}
/**
* Determines whether a raw screen coordinate is within the bounds of the specified view
* #param point - Point containing screen coordinates
* #param view - View to test
* #return true if the point is in the view, else false
*/
protected boolean isPointInView(Point point, View view) {
int[] viewPosition = new int[2];
view.getLocationOnScreen(viewPosition);
int left = viewPosition[0];
int right = left + view.getWidth();
int top = viewPosition[1];
int bottom = top + view.getHeight();
return point.x >= left && point.x <= right && point.y >= top && point.y <= bottom;
}
#SuppressLint("NewApi")
protected boolean isCollision(View view1, View view2) {
boolean collision = false;
do {
if(view1.getY() + view1.getHeight() < view2.getY()) {
break;
}
if(view1.getY() > view2.getY() + view2.getHeight()) {
break;
}
if(view1.getX() > view2.getX() + view2.getWidth()) {
break;
}
if(view1.getX() + view1.getWidth() < view2.getX()) {
break;
}
collision = true;
} while(false);
return collision;
}
protected void selectDropTarget(int index) {
if(index > -1) {
deselectDropTarget();
selectedDropTargetIndex = index;
dropTargets.get(selectedDropTargetIndex).setSelected(true);
}
}
protected void deselectDropTarget() {
if(selectedDropTargetIndex > -1) {
dropTargets.get(selectedDropTargetIndex).setSelected(false);
lastSelectedDropTargetIndex = selectedDropTargetIndex;
selectedDropTargetIndex = -1;
}
}
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I would like to know how to make a layout, like in a Facebook App. I understand, not only me alone looking for it, but I cannot to find the correct words for the search system to find it. And may be here somebody will give me a good link with a sample code. I like a menu, which shows up from the left side in their App.
You can go for any of this link below you like, there are lots of docs and tutorial available.
Android sliding menu demo
Facebook-like slide out navigation for Android
How To Create A Slide-In MenuList, Like In Facebook App
Hope it will help you.
If you need a simple but effective one then you can see the code. I was using it in my last project.
You can download full source code here.
You can check my blog too if it helped you.
Main layout : res/layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<com.banglardin.test_code.SlidingView
xmlns:android = "http://schemas.android.com/apk/res/android"
android:layout_width ="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="#+id/list_activity_layout" >
<!-- Just make your sliding layout here -->
<LinearLayout
android:layout_width ="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#FF34495E"
android:id="#+id/slide_bar_list_activity" >
<!-- All the layout of sliding goes here -->
</LinearLayout>
<!-- Just make your content layout here -->
<LinearLayout
android:layout_width ="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#FF112131"
android:id="#+id/content_bar_list_activity" >
<!-- All the layout of content goes here -->
<RelativeLayout
android:id = "#+id/head1"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:layout_alignParentTop = "true"
android:background="#336699"
android:maxWidth="48dp" >
<ImageButton
android:id ="#+id/main_menu_action_left_of_lable"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:layout_alignParentLeft = "true"
android:layout_centerVertical ="true"
android:layout_weight="1"
android:src="#drawable/option_menu"
android:background="#drawable/all_image_button_press"
android:padding="5dp"/>
<!-- Title lable Of home bar. -->
<TextView
android:id ="#+id/main_toptext"
android:layout_width = "fill_parent"
android:layout_height = "wrap_content"
android:gravity="center"
android:layout_weight="2"
android:shadowDy=".4"
android:shadowDx=".4"
android:clickable="true"
android:shadowRadius=".7"
android:shadowColor="#000000"
android:textColor = "#ffffff"
android:layout_toRightOf="#+id/main_menu_action_left_of_lable"
android:layout_toLeftOf="#+id/main_right_of_lable"
android:layout_centerInParent ="true"
android:textSize = "18dp"
android:layout_centerVertical ="true"
android:padding="5dp"
android:text = " Shiba prasad jana "
android:singleLine = "true"/>
<!-- Search -->
<ImageButton
android:id ="#+id/main_right_of_lable"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:layout_alignParentRight = "true"
android:layout_centerVertical ="true"
android:layout_weight="1"
android:src="#drawable/search_icon"
android:background="#drawable/all_image_button_press"
android:padding="5dp"/>
</RelativeLayout>
</LinearLayout>
MainActivity: src/package_name/MainActivity
package com.banglardin.test_code;
import android.app.*;
import android.os.*;
import android.view.*;
import android.widget.*;
public class MainActivity extends Activity implements SlidingView.Listener {
protected SlidingView mSlidingView;
protected ImageButton menu;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
mSlidingView=(SlidingView)findViewById(R.id.list_activity_layout);
mSlidingView.setListener(this);
menu = (ImageButton) findViewById(R.id.main_menu_action_left_of_lable);
menu.setOnClickListener(new View.OnClickListener(){
public void onClick(View p1){
mSlidingView.toggleSidebar();
}
}
);
}
public void onSidebarOpened() {
}
public void onSidebarClosed() {
}
public boolean onContentTouchedWhenOpening() {
return false;
}
}
SlidingView : src/package_name/SlidingView
package com.banglardin.test_code;
import android.util.*;
import android.view.*;
import android.view.animation.*;
import android.content.Context;
public class SlidingView extends ViewGroup {
public final static int DURATION = 400; // time to show slding animation
protected boolean mPlaceLeft = true;
protected boolean mOpened;
protected View mSidebar;
protected View mContent;
protected int mSidebarWidth =-1; /* assign default value. It will be overwrite
in onMeasure by Layout xml resource. */
protected Animation mAnimation;
protected OpenListener mOpenListener;
protected CloseListener mCloseListener;
protected Listener mListener;
protected boolean mPressed = false;
public SlidingView(Context context) {
this(context, null);
int mSidebarWidth = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,50, getResources().getDisplayMetrics());
}
public SlidingView
(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public void onFinishInflate() {
super.onFinishInflate();
mSidebar = findViewById(R.id.slide_bar_list_activity);
mContent = findViewById(R.id.content_bar_list_activity);
if (mSidebar == null) {
throw new NullPointerException("no view id = animation_sidebar");
}
if (mContent == null) {
throw new NullPointerException("no view id = animation_content");
}
mOpenListener = new OpenListener(mSidebar, mContent);
mCloseListener = new CloseListener(mSidebar, mContent);
}
#Override
public void onLayout(boolean changed, int l, int t, int r, int b) {
/* the title bar assign top padding, drop it */
int sidebarLeft = l;
if (!mPlaceLeft) {
sidebarLeft = r - mSidebarWidth;
}
mSidebar.layout(sidebarLeft,
0,
sidebarLeft + mSidebarWidth,
0 + mSidebar.getMeasuredHeight());
if (mOpened) {
if (mPlaceLeft) {
mContent.layout(l + mSidebarWidth, 0, r + mSidebarWidth, b);
} else {
mContent.layout(l - mSidebarWidth, 0, r - mSidebarWidth, b);
}
} else {
mContent.layout(l, 0, r, b);
}
}
#Override
public void onMeasure(int w, int h) {
super.onMeasure(w, h);
super.measureChildren(w, h);
mSidebarWidth = mSidebar.getMeasuredWidth();
}
#Override
protected void measureChild(View child, int parentWSpec, int parentHSpec) {
/* the max width of Sidebar is 90% of Parent */
if (child == mSidebar) {
int mode = MeasureSpec.getMode(parentWSpec);
int width = (int)(getMeasuredWidth() * 0.9);
super.measureChild(child, MeasureSpec.makeMeasureSpec(width, mode), parentHSpec);
} else {
super.measureChild(child, parentWSpec, parentHSpec);
}
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (!isOpening()) {
return false;
}
int action = ev.getAction();
if (action != MotionEvent.ACTION_UP
&& action != MotionEvent.ACTION_DOWN) {
return false;
}
/* if user press and release both on Content while
* sidebar is opening, call listener. otherwise, pass
* the event to child. */
int x = (int)ev.getX();
int y = (int)ev.getY();
if (mContent.getLeft() < x
&& mContent.getRight() > x
&& mContent.getTop() < y
&& mContent.getBottom() > y) {
if (action == MotionEvent.ACTION_DOWN) {
mPressed = false;
}
if (mPressed
&& action == MotionEvent.ACTION_UP
&& mListener != null) {
mPressed = false;
return mListener.onContentTouchedWhenOpening();
}
} else {
mPressed = false;
}
return false;
}
public void setListener(Listener l) {
mListener = l;
}
/* to see if the Sidebar is visible */
public boolean isOpening() {
return mOpened;
}
public void toggleSidebar() {
if (mContent.getAnimation() != null) {
return;
}
if (mOpened) {
/* opened, make close animation*/
if (mPlaceLeft) {
mAnimation = new TranslateAnimation(0, -mSidebarWidth, 0, 0);
} else {
mAnimation = new TranslateAnimation(0, mSidebarWidth, 0, 0);
}
mAnimation.setAnimationListener(mCloseListener);
} else {
/* not opened, make open animation */
if (mPlaceLeft) {
mAnimation = new TranslateAnimation(0, mSidebarWidth, 0, 0);
} else {
mAnimation = new TranslateAnimation(0, -mSidebarWidth, 0, 0);
}
mAnimation.setAnimationListener(mOpenListener);
}
mAnimation.setDuration(DURATION);
mAnimation.setFillAfter(true);
mAnimation.setFillEnabled(true);
mContent.startAnimation(mAnimation);
}
public void openSidebar() {
if (!mOpened) {
toggleSidebar();
}
}
public void closeSidebar() {
if (mOpened) {
toggleSidebar();
}
}
class OpenListener implements Animation.AnimationListener {
View iSidebar;
View iContent;
OpenListener(View sidebar, View content) {
iSidebar = sidebar;
iContent = content;
}
public void onAnimationRepeat(Animation animation) {
}
public void onAnimationStart(Animation animation) {
iSidebar.setVisibility(View.VISIBLE);
}
public void onAnimationEnd(Animation animation) {
iContent.clearAnimation();
mOpened = !mOpened;
requestLayout();
if (mListener != null) {
mListener.onSidebarOpened();
}
}
}
class CloseListener implements Animation.AnimationListener {
View iSidebar;
View iContent;
CloseListener(View sidebar, View content) {
iSidebar = sidebar;
iContent = content;
}
public void onAnimationRepeat(Animation animation) {
}
public void onAnimationStart(Animation animation) {
}
public void onAnimationEnd(Animation animation) {
iContent.clearAnimation();
iSidebar.setVisibility(View.INVISIBLE);
mOpened = !mOpened;
requestLayout();
if (mListener != null) {
mListener.onSidebarClosed();
}
}
}
public interface Listener
{
public void onSidebarOpened();
public void onSidebarClosed();
public boolean onContentTouchedWhenOpening();
}
}