I would like to start animation when view is long clicked.
The code is as follows.
public class Example_Dialog extends Dialog implements AnimationListener{
TextView view_Description1 = null;
View view_Button1 = null;
MessageCreateTask task;
public Example_Dialog( Context context , int theme ){
super( context , theme );
setContentView(R.layout.infomation_dialog);
view_Button1 = findViewById(R.id.common_dialog_button_1);
view_Description1 = (TextView)findViewById(R.id.common_dialog_description_1);
view_Description1.setHeight(0);
view_Button1.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
task = new MessageCreateTask(view_Description1);
task.execute();
}
});
}
#Override
public void onAnimationEnd(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationStart(Animation animation) {
}
class MessageCreateTask extends AsyncTask<Void, Void, String> {
TextView textView;
String messageOutput;
int totalLineNum;
public MessageCreateTask(TextView textView) {
this.textView = textView;
messageOutput = "";
totalLineNum = 0;
}
#Override
protected void onPreExecute() {
}
#Override
protected String doInBackground(Void... params) {
for( int i= 0 ; i< 10 ; i++ ){
messageOutput += "a" + "<br>";
totalLineNum++;
}
return messageOutput;
}
#Override
protected void onPostExecute(String message) {
int dialogWidth = 838;
int dialogHeight = 26*totalLineNum;
textView.setWidth( dialogWidth );
textView.setText(Html.fromHtml(message));
HeightAnimation hanime_open = new HeightAnimation(textView , 0 , dialogHeight );
hanime_open = new HeightAnimation(textView , 0 , dialogHeight );
hanime_open.setDuration(300);
textView.startAnimation(hanime_open);
}
}
}
public class HeightAnimation extends Animation {
int targetHeight;
int startHeight;
TextView textView;
public HeightAnimation(TextView textView,int startHeight, int targetHeight) {
this.textView = textView;
this.targetHeight = targetHeight;
this.startHeight = startHeight;
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
int newHeight = (int)(startHeight + (targetHeight - startHeight)*interpolatedTime);
textView.setHeight(newHeight);
if( (startHeight != 0) && (newHeight == 0) ){
textView.setVisibility(View.GONE);
}
}
#Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, ((View)textView.getParent()).getWidth(), parentHeight);
}
}
The animation was not started with the above code, but it was started by replacing onclick with onlongclick like as below.
view_Button1.setOnLongClickListener(new View.OnLongClickListener(){
public boolean onLongClick(View v){
task = new MessageCreateTask(view_Description1);
task.execute();
return true;
}
});
I want to know the reason why animation does not start in case of onclick.
The reason why it is not working with onClickListener() is, that the view hasnĀ“t the Focus. So you Need to press the button twice or you have to use a onlongClickListener(). To make the view clickable the first time, do the following:
enable focusable in touch mode, wether in your XML layout as attribute:
android:focusableInTouchMode="true"
or programmatically after you have initialized the button:
view_button1.setFocusableInTouchMode(true);
Then you can set the Focus to the view simply:
view_button1.requestFocus();
Related
I have two RelativeLayouts which contains one TextView each.
Basically the top layout serves as a "button". When clicked, the other layout will have its animation played (expanding downwards).
In this situation, to which layout should I add setLayoutAnimationListener() so that the top layout will not be able to be clicked in method onAnimationStart() and can be clicked in method onAnimationEnd()?
Here are the layouts I meant :
<RelativeLayout
android:id="#+id/activity_signup_step_one_dropdownTitleWrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/activity_signup_step_one_orangEmailWrapper"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp">
<TextView
android:id="#+id/activity_signup_step_one_dropdownTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/stepOneTitle"/>
</RelativeLayout>
<RelativeLayout
android:id="#+id/activity_signup_step_one_dropdownTextWrapper"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/activity_signup_step_one_dropdownTitleWrapper">
<TextView
android:id="#+id/activity_signup_step_one_dropdownText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/stepOneMessage"/>
</RelativeLayout>
The java class
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_signup_step_one);
...
RelativeLayout dropDownTitle = (RelativeLayout)findViewById(R.id.activity_signup_step_one_dropdownTitleWrapper);
RelativeLayout dropDownMessage = (RelativeLayout)findViewById(R.id.activity_signup_step_one_dropdownTextWrapper);
dropDownMessage.setVisibility(View.GONE);
dropDownTitle.setOnClickListener(translateHandler);
dropDownMessage.setLayoutAnimationListener(new Animation.AnimationListener() {
//RelativeLayout touchDisabler = (RelativeLayout) findViewById(R.id.activity_signup_step_one_dropdownTitleWrapper_filler);
RelativeLayout dropDownTitle = (RelativeLayout) findViewById(R.id.activity_signup_step_one_dropdownTitleWrapper);
#Override
public void onAnimationStart(Animation animation) {
//touchDisabler.setClickable(true);
Log.d("onStart", "Start");
dropDownTitle.setClickable(false);
//getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
//WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
}
#Override
public void onAnimationEnd(Animation animation) {
//touchDisabler.setClickable(false);
Log.d("onEnd", "End");
dropDownTitle.setClickable(true);
//getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
}
#Override
public void onAnimationRepeat(Animation animation) {
//touchDisabler.setClickable(true);
}
});
int height;
View.OnClickListener translateHandler = new View.OnClickListener() {
#Override
public void onClick(View v) {
RelativeLayout dropDownMessage = (RelativeLayout)findViewById(R.id.activity_signup_step_one_dropdownTextWrapper);
TextView testText = (TextView)findViewById(R.id.activity_signup_step_one_dropdownText);
if(dropDownMessage.getVisibility() == View.VISIBLE){
MyCustomAnimation a = new MyCustomAnimation(dropDownMessage, 350, MyCustomAnimation.COLLAPSE);
height = a.getHeight();
testText.setText(getResources().getString(R.string.stepOneMessage));
dropDownMessage.startAnimation(a);
}else{
MyCustomAnimation a = new MyCustomAnimation(dropDownMessage, 350, MyCustomAnimation.EXPAND);
a.setHeight(height);
testText.setText(getResources().getString(R.string.stepOneMessage));
dropDownMessage.startAnimation(a);
}
}
};
Here's the animation class which might be useful
public class MyCustomAnimation extends Animation {
public final static int COLLAPSE = 1;
public final static int EXPAND = 0;
private View mView;
private int mEndHeight;
private int mType;
private RelativeLayout.LayoutParams mLayoutParams;
public MyCustomAnimation(View view, int duration, int type) {
setDuration(duration);
mView = view;
mEndHeight = mView.getHeight();
mLayoutParams = ((RelativeLayout.LayoutParams) view.getLayoutParams());
mType = type;
if(mType == EXPAND) {
mLayoutParams.height = 0;
} else {
mLayoutParams.height = LayoutParams.WRAP_CONTENT;
}
view.setVisibility(View.VISIBLE);
}
public int getHeight(){
return mView.getHeight();
}
public void setHeight(int height){
mEndHeight = height;
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
if (interpolatedTime < 1.0f) {
if(mType == EXPAND) {
mLayoutParams.height = (int)(mEndHeight * interpolatedTime);
} else {
mLayoutParams.height = (int) (mEndHeight * (1 - interpolatedTime));
}
mView.requestLayout();
} else {
if(mType == EXPAND) {
mLayoutParams.height = LayoutParams.WRAP_CONTENT;
mView.requestLayout();
}else{
mView.setVisibility(View.GONE);
}
}
}
}
final RelativeLayout dropDownTitle = (RelativeLayout) findViewById(R.id.activity_signup_step_one_dropdownTitleWrapper);
dropDownMessage.setLayoutAnimationListener(new Animation.AnimationListener() {
//RelativeLayout touchDisabler = (RelativeLayout) findViewById(R.id.activity_signup_step_one_dropdownTitleWrapper_filler);
#Override
public void onAnimationStart(Animation animation) {
//touchDisabler.setClickable(true);
Log.d("onStart", "Start");
dropDownTitle.setClickable(false);
dropDownMessage.setVisibility(View.GONE);
//getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
//WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
}
#Override
public void onAnimationEnd(Animation animation) {
//touchDisabler.setClickable(false);
Log.d("onEnd", "End");
dropDownTitle.setClickable(true);
//getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
}
#Override
public void onAnimationRepeat(Animation animation) {
//touchDisabler.setClickable(true);
}
});
Try to instantiate your RelativeLayout outside of your anonymous inner class (AnimationListener) - and of course declare it final.
I want to change my Relative layout's background every 10 seconds with fade in/fade out animation.
So I found
//Transitiondrawable
TransitionDrawable transition = (TransitionDrawable) viewObj.getBackground();
transition.startTransition(transitionTime);
But it supports only 2 Drawable and I want to add more
Is there any way to do this?
First implement MyAnim.java class as below:
public class MyAnim extends Animation {
private final RelativeLayout view;
private int targetBackGround;
public MyAnim(RelativeLayout view, int tagetBackGroundColor) {
this.view = view;
this.targetBackGround = tagetBackGroundColor;
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
view.setBackgroundColor(targetBackGround);
}
public void setColor(int color) {
this.targetBackGround = color;
}
}
Then add below code to your activity and call that animateBackground() method wherever you want:
private MyAnim backgroundAnim;
private int i;
private void animateBackground(){
final RelativeLayout animLay = (RelativeLayout) findViewById(R.id.animLay);
final int colors[] = new int[]{Color.RED, Color.CYAN, Color.DKGRAY, Color.GREEN, Color.MAGENTA};
backgroundAnim = new MyAnim(animLay, colors[i]);
backgroundAnim.setDuration(1000);
animLay.startAnimation(backgroundAnim);
backgroundAnim.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
if (i == colors.length - 1) {
i = 0;
} else {
i++;
}
backgroundAnim.setColor(colors[i]);
animLay.startAnimation(backgroundAnim);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
}
You can create your own loop, something like:
int delayBetweenAnimations = 10000;
for (int i = 0; i < yourImagesArray.length ; i++) {
int delay = i * delayBetweenAnimations;
yourImageview.postDelayed(new Runnable() {
#Override
public void run() {
//set your image and animation here
}
}, delay);
}
Another way is to use recursive animation:
#Override
public void onAnimationEnd(Animator animation) {
if(check_if_you_Still_want to_loop){
//rerun your animation
}
}
In my scenario if I click on a expanded card from card_1 then all other cards should be invisible. Also, can I change the positions of the card runtime so it can move 2nd card on the position of the first and it will expand to full screen so there will be no need to hide other cards.
Please check the attached image.
public class DashboardMarketAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int VIEW_TYPE_TOP_MENU = 0;
private static final int VIEW_TYPE_MARKET_MOVERS = 1;
private static final int VIEW_TYPE_DERIVATIVES = 2;
private static final int VIEW_TYPE_NEWS = 3;
private final Context context;
private final String[] menuItems;
public DashboardMarketAdapter(Context context, String[] menuItems) {
super();
this.context = context;
this.menuItems = menuItems;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v;
switch (viewType) {
case VIEW_TYPE_TOP_MENU:
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_top_view, parent, false);
return new TopMenuViewHolder(v, parent.getContext());
case VIEW_TYPE_MARKET_MOVERS:
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_market_movers, parent, false);
return new MarketMoversViewHolder(v, parent.getContext());
case VIEW_TYPE_DERIVATIVES:
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_market_derivatives, parent, false);
return new MarketDerivativesViewHolder(v);
case VIEW_TYPE_NEWS:
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_top_news, parent, false);
return new TopNewsViewHolder(v);
default:
throw new RuntimeException("there is no type that matches the type " + viewType + " + make sure your using types correctly");
}
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
}
/**
* The length of the string array will tell recycler view the count of the card views.
*/
#Override
public int getItemCount() {
return menuItems.length;
}
/**
* #param position this will return the view of the card according to the position of the card.
*/
#Override
public int getItemViewType(int position) {
switch (position) {
case VIEW_TYPE_TOP_MENU:
return VIEW_TYPE_TOP_MENU;
case VIEW_TYPE_MARKET_MOVERS:
return VIEW_TYPE_MARKET_MOVERS;
case VIEW_TYPE_DERIVATIVES:
return VIEW_TYPE_DERIVATIVES;
case VIEW_TYPE_NEWS:
return VIEW_TYPE_NEWS;
default:
return 0;
}
}
/**
* This view holder is holding the view of topmost card,
* which contains tab and viewpager.
*/
static class TopMenuViewHolder extends RecyclerView.ViewHolder {
#InjectView(R.id.pager)
ViewPager top_view_pager;
#InjectView(R.id.tabs)
DashboardSlidingTabLayout top_view_tabs;
#InjectView(R.id.expand)
Button btnExpand;
#InjectView(R.id.card_view)
CardView cardView;
private DashboardTabAdapter adapter;
private CharSequence Titles[];
private int NumberOfTabs;
int pos;
static int setView = 0;
int minHeight;
public static final int TOP_VIEW = 0;
public static final int INDICES = 1;
public static final int COMMODITY = 2;
public static final int CURRENCY = 3;
public TopMenuViewHolder(View itemView, final Context context) {
super(itemView);
ButterKnife.inject(this, itemView);
Titles = context.getResources().getStringArray(R.array.string_array_dashboard_tab_menu);
Bundle bundle = new Bundle();
bundle.putInt("setView", setView);
NumberOfTabs = Titles.length;
adapter = new DashboardTabAdapter(((FragmentActivity) context).getSupportFragmentManager(), Titles, NumberOfTabs, bundle);
top_view_pager.setAdapter(adapter);
top_view_tabs.setViewPager(top_view_pager);
/**
* Here visibility of Expand button is decided upon the tab selected.
*/
top_view_pager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
pos = position;
if (position > 0) {
btnExpand.setVisibility(View.VISIBLE);
initializeTab();
} else if (position == 0) {
btnExpand.setVisibility(View.GONE);
collapseView();
}
}
});
/**
* This will be used to give initial height for the top card.
*/
cardView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
cardView.getViewTreeObserver().removeOnPreDrawListener(this);
minHeight = cardView.getHeight();
ViewGroup.LayoutParams layoutParams = cardView.getLayoutParams();
layoutParams.height = minHeight;
cardView.setLayoutParams(layoutParams);
return true;
}
});
/**
* Here you can get the height of the screen
*/
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics dimension = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(dimension);
final int height = dimension.heightPixels;
/**
* Here you can add logic for expanding a card.
*/
btnExpand.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.i("Dashboard", "Current Fragment" + top_view_pager.getCurrentItem());
new ChildRecyclerView(context, true);
new ParentRecyclerView(context, false);
toggleCardViewnHeight(height);
}
});
}
/**
* This method will toggle expand and collapse of card view.
*/
private void toggleCardViewnHeight(int height) {
int ViewMinHeight = minHeight;
if (cardView.getHeight() == ViewMinHeight) {
// expand
expandView(height);
} else {
// collapse
collapseView();
}
}
/**
* This method will initialize tab adapter depending upon the page selected.
*/
public void initializeTab() {
switch (top_view_pager.getCurrentItem()) {
case INDICES:
((IndicesFragment) adapter.getRegisteredFragment(INDICES)).initUI();
break;
case COMMODITY:
((CommodityDashboardFragment) adapter.getRegisteredFragment(COMMODITY)).initUI();
break;
case CURRENCY:
((CurrencyDashboardFragment) adapter.getRegisteredFragment(CURRENCY)).initUI();
break;
}
}
/**
* Collapse View Animation
*/
public void collapseView() {
BaseFragment.isExpanded = 0;
ValueAnimator anim = ValueAnimator.ofInt(cardView.getMeasuredHeightAndState(),
minHeight);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
int val = (Integer) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams layoutParams = cardView.getLayoutParams();
layoutParams.height = val;
cardView.setLayoutParams(layoutParams);
}
});
anim.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
}
#Override
public void onAnimationEnd(Animator animation) {
initializeTab();
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
anim.start();
}
/**
* Expand View Animation
*/
public void expandView(int height) {
BaseFragment.isExpanded = 1;
ValueAnimator anim = ValueAnimator.ofInt(cardView.getMeasuredHeightAndState(),
height);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
int val = (Integer) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams layoutParams = cardView.getLayoutParams();
layoutParams.height = val;
cardView.setLayoutParams(layoutParams);
}
});
anim.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
}
#Override
public void onAnimationEnd(Animator animation) {
initializeTab();
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
anim.start();
}
}
/**
* This view holder is holding the view of MarketMovers card,
*/
static class MarketMoversViewHolder extends RecyclerView.ViewHolder {
#InjectView(R.id.btnExpand)
Button btnExpand;
#InjectView(R.id.card_view)
CardView cardView;
#InjectView(R.id.relativeLayout)
RelativeLayout relativeLayout;
int height;
String []menuItem={"MARKET MOVERS","DERIVATIVES","TOP NEWS"};
public MarketMoversViewHolder(View itemView, final Context context) {
super(itemView);
ButterKnife.inject(this, itemView);
relativeLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
relativeLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
height = relativeLayout.getHeight();
ViewGroup.LayoutParams layoutParams = cardView.getLayoutParams();
layoutParams.height = 400;
cardView.setLayoutParams(layoutParams);
}
});
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics dimension = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(dimension);
int width = dimension.widthPixels;
final int screenHeight = dimension.heightPixels;
final int fullHeight = screenHeight - 400;
btnExpand.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
toggleCardViewnHeight(fullHeight);
DashboardMarketAdapter DM =new DashboardMarketAdapter(context,menuItem);
DM.notifyDataSetChanged();
}
});
}
private void toggleCardViewnHeight(int height) {
int ViewMinHeight = 400;
if (cardView.getHeight() == ViewMinHeight) {
// expand
ValueAnimator anim = ValueAnimator.ofInt(cardView.getMeasuredHeightAndState(),
height);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
int val = (Integer) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams layoutParams = cardView.getLayoutParams();
layoutParams.height = val;
cardView.setLayoutParams(layoutParams);
}
});
anim.start();
} else {
// collapse
ValueAnimator anim = ValueAnimator.ofInt(cardView.getMeasuredHeightAndState(),
ViewMinHeight);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
int val = (Integer) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams layoutParams = cardView.getLayoutParams();
layoutParams.height = val;
cardView.setLayoutParams(layoutParams);
}
});
anim.start();
}
}
}
/**
* This view holder is holding the view of Derivatives card,
*/
private class MarketDerivativesViewHolder extends RecyclerView.ViewHolder {
public MarketDerivativesViewHolder(View v) {
super(v);
}
}
/**
* This view holder is holding the view of NEWS card,
*/
private class TopNewsViewHolder extends RecyclerView.ViewHolder {
public TopNewsViewHolder(View v) {
super(v);
}
}
}
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 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.