拋棄Residemenu來實現QQ5.0UI,residemenuqq5.0ui
轉載清註明:http://blog.csdn.net/eclipsexys
自從QQ 5.0發布,新的QQ UI就成了大家模仿的眾矢之地,不過大家模仿的時候,一般都會使用到一個開原始檔控制,Residemenu,相信大家對這個開源架構還是很熟悉的,剛出來的時候,確實很驚豔,但是,對於初學者或者只是想實現一個很簡單的效果的朋友來說,用這個架構就有點大材小用了,其實,利用Android原生的控制項,我們也能實現這樣一個酷眩的效果,今天的主角是SlidingPaneLayout,這個組件是在support v4裡面新增的控制項,不熟悉的朋友可以看看support v4裡面的sample,非常簡單。
國際慣例,先:
大家可以看見,跟Residemenu實現的效果基本一致。
結構非常簡單,一個容器,2個fragment,就完成了。
讓我們現來看看布局:
容器類:
<android.support.v4.widget.SlidingPaneLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:id="@+id/main" android:background="@drawable/main_bg" android:layout_height="match_parent" > <FrameLayout android:id="@+id/main_menu" android:layout_width="200dp" android:layout_height="match_parent" > </FrameLayout> <FrameLayout android:id="@+id/main_container" android:layout_width="match_parent" android:layout_height="match_parent" > </FrameLayout></android.support.v4.widget.SlidingPaneLayout>
就是SlidingPaneLayout裡面放了2個fragment,第一個預設是左邊的,也就是初始隱藏的,第2個就是右邊滑動的
讓我們再來看看2個fragment:
Menu fragment:
package com.xys.fastword.fragment;import android.app.Fragment;import android.os.Bundle;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import com.xys.fastword.R;public class MenuFragment extends Fragment {@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {return inflater.inflate(R.layout.menu_frg, container, false);}}
布局:
<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" android:background="@null" > <LinearLayout android:id="@+id/ll" android:layout_width="match_parent" android:layout_height="40dp" android:layout_marginTop="30dp" android:gravity="center_vertical" > <ImageView android:id="@+id/imageView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:src="@drawable/ic_launcher" /> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> </LinearLayout> <View android:id="@+id/separator1" android:layout_width="match_parent" android:layout_height="1dp" android:layout_below="@id/ll" android:layout_marginLeft="20dp" android:layout_marginRight="20dp" android:layout_marginTop="20dp" android:background="#000000" /> <LinearLayout android:id="@+id/ll1" android:layout_width="match_parent" android:layout_height="40dp" android:layout_below="@+id/separator1" android:layout_marginTop="30dp" android:gravity="center_vertical" > <ImageView android:id="@+id/imageView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:src="@drawable/ic_launcher" /> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> </LinearLayout> <LinearLayout android:id="@+id/ll2" android:layout_width="match_parent" android:layout_height="40dp" android:layout_below="@+id/ll1" android:layout_marginTop="30dp" android:gravity="center_vertical" > <ImageView android:id="@+id/imageView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:src="@drawable/ic_launcher" /> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> </LinearLayout> <View android:id="@+id/separator2" android:layout_width="match_parent" android:layout_height="1dp" android:layout_below="@+id/ll2" android:layout_marginLeft="20dp" android:layout_marginRight="20dp" android:layout_marginTop="40dp" android:background="#000000" /> <LinearLayout android:id="@+id/ll3" android:layout_width="match_parent" android:layout_height="40dp" android:layout_alignParentLeft="true" android:layout_below="@+id/separator2" android:layout_marginTop="34dp" android:gravity="center_vertical" > <ImageView android:id="@+id/ImageView01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:src="@drawable/ic_launcher" /> <TextView android:id="@+id/TextView01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> </LinearLayout> <LinearLayout android:id="@+id/ll4" android:layout_width="match_parent" android:layout_height="40dp" android:layout_alignParentLeft="true" android:layout_below="@+id/ll3" android:layout_marginTop="34dp" android:gravity="center_vertical" > <ImageView android:id="@+id/ImageView01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:src="@drawable/ic_launcher" /> <TextView android:id="@+id/TextView01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> </LinearLayout></RelativeLayout>
Container Fragment:
package com.xys.fastword.fragment;import android.animation.Animator;import android.animation.AnimatorListenerAdapter;import android.animation.ObjectAnimator;import android.animation.PropertyValuesHolder;import android.app.Fragment;import android.os.Bundle;import android.view.LayoutInflater;import android.view.View;import android.view.View.OnClickListener;import android.view.ViewGroup;import android.view.animation.BounceInterpolator;import android.widget.ImageView;import android.widget.TextView;import com.xys.fastword.R;public class ContainerFragment extends Fragment implements OnClickListener {private ImageView ivRecite;private View view;private TextView tvTitle;private ImageView btnLeft;private ImageView btnRight;@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {view = inflater.inflate(R.layout.container_frg, container, false);ivRecite = (ImageView) view.findViewById(R.id.iv_recite);ivRecite.setOnClickListener(this);return view;}@Overridepublic void onClick(View v) {final View view = v;PropertyValuesHolder pvX = PropertyValuesHolder.ofFloat("scaleX", 1F,0.8F, 1F);PropertyValuesHolder pvY = PropertyValuesHolder.ofFloat("scaleY", 1F,0.8F, 1F);ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(v, pvX,pvY);animator.setInterpolator(new BounceInterpolator());animator.start();animator.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationEnd(Animator animation) {super.onAnimationEnd(animation);switch (view.getId()) {case R.id.iv_recite:break;default:break;}}});}}
布局:
<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:background="@android:color/holo_blue_bright" android:orientation="vertical" > <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" > <ImageView android:id="@+id/iv_recite" android:layout_width="120dp" android:layout_height="120dp" android:layout_marginLeft="30dp" android:layout_marginTop="30dp" android:background="#777777" /> <ImageView android:id="@+id/imageView2" android:layout_width="120dp" android:layout_height="120dp" android:layout_below="@id/iv_recite" android:layout_marginLeft="30dp" android:layout_marginTop="20dp" android:background="#777777" android:src="@drawable/ic_launcher" /> <ImageView android:id="@+id/imageView3" android:layout_width="120dp" android:layout_height="260dp" android:layout_marginLeft="20dp" android:layout_marginTop="30dp" android:layout_toRightOf="@id/iv_recite" android:background="#777777" android:src="@drawable/ic_launcher" /> <ImageView android:id="@+id/imageView4" android:layout_width="260dp" android:layout_height="120dp" android:layout_below="@id/imageView2" android:layout_marginLeft="30dp" android:layout_marginTop="20dp" android:background="#777777" android:src="@drawable/ic_launcher" /> </RelativeLayout></LinearLayout>
為了娛樂,我給布局的一個imageview加了個點擊動畫,不需要的可以無視。
最後,在容器中就可以來控制了:
package com.xys.fastword.activity;import android.app.Activity;import android.app.FragmentManager;import android.app.FragmentTransaction;import android.os.Bundle;import android.support.v4.widget.SlidingPaneLayout;import android.support.v4.widget.SlidingPaneLayout.PanelSlideListener;import android.view.View;import android.widget.FrameLayout;import com.xys.fastword.R;import com.xys.fastword.fragment.ContainerFragment;import com.xys.fastword.fragment.MenuFragment;public class MainActivity extends Activity {private SlidingPaneLayout mSPLMain;private FrameLayout mFLMenu;private FrameLayout mFLContainer;private FragmentManager mFrgManager;private FragmentTransaction mFrgTransaction;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.fw_main);mFrgManager = getFragmentManager();initViews();bindEvents();}private void bindEvents() {mSPLMain.setPanelSlideListener(new PanelSlideListener() {@Overridepublic void onPanelSlide(View arg0, float v) {mFLMenu.setScaleY(v / 2 + 0.5F);mFLMenu.setScaleX(v / 2 + 0.5F);mFLMenu.setAlpha(v);mFLContainer.setScaleY(1 - v / 5);}@Overridepublic void onPanelOpened(View arg0) {}@Overridepublic void onPanelClosed(View arg0) {}});}private void initViews() {mSPLMain = (SlidingPaneLayout) findViewById(R.id.main);mFLMenu = (FrameLayout) findViewById(R.id.main_menu);mFLContainer = (FrameLayout) findViewById(R.id.main_container);mFrgTransaction = mFrgManager.beginTransaction();mFrgTransaction.add(R.id.main_menu, new MenuFragment(), "mMenuFrg");mFrgTransaction.add(R.id.main_container, new ContainerFragment(),"mContainerFrg");mFrgTransaction.commit();}}
實現效果的關鍵就在於setPanelSlideListener中的onPanelSlide(View arg0, float v)的參數v:
參數v就是滑動時的距離參數,0-1的變化,那麼,我們就可以根據這個值來通過各種函數的變化,來擷取我們所需要的值,這樣就實現了一個插值器了,實現動畫也就so easy了。