布局animationAndroid

我想animation两种不同的布局

我想要的方式

我已经按照我想要的方式制作了animation,我只是想为不同的XML布局制作animation。 有一个类LayoutAnimationController,但我真的不知道如何使用它。 有人可以指出我正确的方向,有一个例子或好的解释。

下面是我用来制作animation的代码。

TranslateAnimation slide = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 300f, 0,0 ); slide.setAnimationListener(AL); slide.setFillAfter(true); slide.setDuration(1000); parentlayout.startAnimation(slide); 

更新由于许多向上投票,我决定将示例项目放入Git存储库。 请参阅我的链接答案。

好了花了2天时间阅读有关similair问题以及人们如何解决这些问题后,我终于能够创造出我想要的东西了。 我无法使用2个不同的XML文件,但我怀疑它是不可能的。

我确实遇到了一些问题。

第一个animation结束后,该按钮无法点击。 这是因为animation显示所有内容都已移动但不更新布局,因此按钮仍处于animation开始的位置。 所以我不得不计算布局的新位置。

我想我在某处看过这不再是3.0的问题,但如果我错了,请纠正我

另一个是当我让我的animation最终工作的时候,我希望我的底层视图在animation结束之前view.setVisabilty(View.GONE);因为我调用了view.setVisabilty(View.GONE); 。 现在问题是当我没有调用那个方法时,animation只挂了一秒然后射击到animation的结束位置。 所以我在GONE上添加了一个空的LinearLayout(可以是任何东西),Default属性,当animation开始时将它设置为Visible。 恢复animation时,再将其设置为已消失。 在这之后animation按照我想要的方式工作。

如果您使用的是Rel,Linear或任何其他布局。 然后你不能在Z顺序堆叠视图,所以你必须使用SurfaceView。

所以inheritancemain.xml

  < ?xml version="1.0" encoding="utf-8"?>               

inheritance了java代码

  public class MenuAnimationActivity extends Activity { private Button buttonSwitch; private View subLayout; private View topLayout; private ListView subViewListView; private String listViewDummyContent[]={"Android","iPhone","BlackBerry","AndroidPeople"}; private Display display; private View fakeLayout; private AnimationListener AL; // Values for after the animation private int oldLeft; private int oldTop; private int newleft; private int newTop; private int screenWidth; private int animToPostion; // TODO change the name of the animToPostion for a better explanation. private boolean menuOpen = false; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); buttonSwitch = (Button)findViewById(R.id.button); subLayout = (View) findViewById(R.id.layout); topLayout = (View) findViewById(R.id.layoutTwo); subViewListView=(ListView)findViewById(R.id.listView1); fakeLayout = (View)findViewById(R.id.fake_layouy); subViewListView.setAdapter(new ArrayAdapter(this,android.R.layout.simple_list_item_1 , listViewDummyContent)); display = getWindowManager().getDefaultDisplay(); screenWidth = display.getWidth(); int calcAnimationPosition = (screenWidth /3); // Value where the onTop Layer has to animate // also the max width of the layout underneath // Set Layout params for subLayout according to calculation animToPostion = screenWidth - calcAnimationPosition; RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(animToPostion, RelativeLayout.LayoutParams.FILL_PARENT); subLayout.setLayoutParams(params); topLayout.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if(event.getAction() == MotionEvent.ACTION_DOWN) { if (menuOpen == true) { animSlideLeft(); } } return false; } }); buttonSwitch.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(menuOpen == false){ animSlideRight(); } else if (menuOpen == true) { animSlideLeft(); } } }); AL = new AnimationListener() { @Override public void onAnimationStart(Animation animation) { buttonSwitch.setClickable(false); topLayout.setEnabled(false); } @Override public void onAnimationRepeat(Animation animation) { // TODO Auto-generated method stub } @Override public void onAnimationEnd(Animation animation) { if(menuOpen == true) { Log.d("", "Open"); topLayout.layout(oldLeft, oldTop, oldLeft + topLayout.getMeasuredWidth(), oldTop + topLayout.getMeasuredHeight() ); menuOpen = false; buttonSwitch.setClickable(true); topLayout.setEnabled(true); } else if(menuOpen == false) { Log.d("","FALSE"); topLayout.layout(newleft, newTop, newleft + topLayout.getMeasuredWidth(), newTop + topLayout.getMeasuredHeight() ); topLayout.setEnabled(true); menuOpen = true; buttonSwitch.setClickable(true); } } }; } public void animSlideRight(){ fakeLayout.setVisibility(View.VISIBLE); newleft = topLayout.getLeft() + animToPostion; newTop = topLayout.getTop(); TranslateAnimation slideRight = new TranslateAnimation(0,newleft,0,0); slideRight.setDuration(500); slideRight.setFillEnabled(true); slideRight.setAnimationListener(AL); topLayout.startAnimation(slideRight); } public void animSlideLeft() { fakeLayout.setVisibility(View.GONE); oldLeft = topLayout.getLeft() - animToPostion; oldTop = topLayout.getTop(); TranslateAnimation slideLeft = new TranslateAnimation(newleft,oldLeft,0,0); slideLeft.setDuration(500); slideLeft.setFillEnabled(true); slideLeft.setAnimationListener(AL); topLayout.startAnimation(slideLeft); } } 

我在触摸视图和内容时做了一些额外的编码。

最后的结果

在animation之前

在此处输入图像描述

在第一次animation之后

在此处输入图像描述

在第二个animation回到左边后,它将返回第一个图像。

那些帮助我的post确实值得一些信用,但我找不到任何一个。

编辑

GIT https://bitbucket.org/maikelbollemeijer/sidepanelswitcher

更新: https : //github.com/jfeinstein10/SlidingMenu此lib与Actionbar Sherlock兼容。

希望这可以帮助

我有类似的要求,使布局animation像Facebook应用程序。 为此,我制作了一个自定义的ViewGroup(称为AnimationLayout)。 希望这些代码有所帮助

AnimationLayout需要两个子项:侧栏和内容。 (通过将@ + id / animation_sidebar和@ + id / animation_content分配给相应的一个)

这是布局xml,SideBar有一个按钮和一个列表视图。 内容有一个textview和一个按钮(它绑定到一个回调函数)。

 < ?xml version="1.0" encoding="utf-8"?>           

这是测试活动。 它初始化ListView并将自己指定为AnimationLayout的监听器。

 package test.julian.hello; import org.zeroxlab.widget.AnimationLayout; import android.app.Activity; import android.app.ActivityManager; import android.os.Bundle; import android.widget.*; import android.util.Log; import android.view.View; public class HelloAndroid extends Activity implements AnimationLayout.Listener { ListView mList; AnimationLayout mLayout; String[] mStrings = {"a", "b", "c", "d", "e", "f", "g"}; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.app_layout); mLayout = (AnimationLayout) findViewById(R.id.animation_layout); mLayout.setListener(this); mList = (ListView) findViewById(R.id.sidebar_list); mList.setAdapter( new ArrayAdapter( this, android.R.layout.simple_list_item_multiple_choice , mStrings)); mList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); } public void onClickButton(View v) { mLayout.toggleSidebar(); } @Override public void onSidebarOpened() { Log.d("Foo", "opened"); } @Override public void onSidebarClosed() { Log.d("Foo", "opened"); } @Override public boolean onContentTouchedWhenOpening() { Log.d("Foo", "going to close sidebar"); mLayout.closeSidebar(); return true; } } 

这是AnimationLayout。

 /* * Copyright (C) 2012 0xlab - http://0xlab.org/ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Authored by Julian Chu  */ package org.zeroxlab.widget; import test.julian.hello.R; import android.content.Context; import android.util.AttributeSet; import android.view.animation.Animation; import android.view.animation.TranslateAnimation; import android.view.MotionEvent; import android.view.View; import android.view.View.MeasureSpec; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; public class AnimationLayout extends ViewGroup { public final static int DURATION = 500; protected boolean mOpened; protected View mSidebar; protected View mContent; protected int mSidebarWidth = 150; // by default 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_sidebar); mContent = findViewById(R.id.animation_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 */ mSidebar.layout(l, 0, l + mSidebarWidth, 0 + mSidebar.getMeasuredHeight()); if (mOpened) { 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*/ mAnimation = new TranslateAnimation(0, -mSidebarWidth, 0, 0); mAnimation.setAnimationListener(mCloseListener); } else { /* not opened, make open animation */ 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(); } } 

当SideBar关闭时,它看起来像这样。

http://i.stack.imgur.com/tynLw.png

当SideBar打开时,它看起来像这样。

http://i.stack.imgur.com/QJC8q.png

我从walkice( https://github.com/walkingice/gui-sliding-sidebar )获取解决方案并添加到其中,制作一个小部件,其中“侧边栏”可以从顶部或底部以及左侧进入或者是对的。 您还可以将侧边栏宽度(或高度)指定为父宽度(或高度)的百分比。 侧边栏可以固定在主内容视图后面或滑入。

该项目由SolutionStream提供,可在此处获取: https : //github.com/solutionstream/sidebarlayout

它是开源的(Apache 2.0许可证),因此可以随意查看代码并使用它(在许可证下),作为示例或直接使用。

披露:上面的链接是我在SolutionStream自己创建的项目。