前言:
前幾天想實作一下側邊欄的抽屜。找了原廠的 drawerLayout,感覺效果不如預期。不夠彈性。
於是我實作了一個抽屜效果。
實作:
![]() |
| 今日要實作的地方 |
程式碼有點多,讓我們先從動畫著手吧。
一、側邊欄動畫效果
二、首頁和側邊欄的製作
三、MainActivity程式的串接
一、側邊欄動畫效果
先在res下創建一個anim
開兩個檔案,menu_push_in and menu_push_out
menu_push_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="250"
android:fillAfter="true"
android:fromXDelta="0.0"
android:toXDelta="+85%p" />
</set>
menu_push_out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="250"
android:fromXDelta="85.0%"
android:toXDelta="0.0"
/>
</set>
/***duration 動畫持續時間
*fromXDelta 依賴x軸,動畫起始的地方百分比
*toXDelta 依賴x軸,動畫結束的地方百分比
*/
接下來製作MenuController來實作動畫的效果。
MenuController.java
public class MenuController {
public static void pushRight(final Context context, final RelativeLayout layout) {
Animation mAnimIn = AnimationUtils.loadAnimation(context, R.anim.menu_push_in);
layout.startAnimation(mAnimIn);
mAnimIn.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
//動畫結束後,Hold住畫面
TranslateAnimation anim = new TranslateAnimation(0.0f, 0.0f, 0.0f, 0.0f);
anim.setDuration(1);
layout.startAnimation(anim);
int realWidth = (context.getResources().getDisplayMetrics().widthPixels);
int left = (int) (realWidth * 0.85);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(layout.getLayoutParams());
params.setMargins(left, 0, -(realWidth + left), 0);
layout.setLayoutParams(params);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
}
public static void pushLeft(final Context context, RelativeLayout layout) {
Animation mAnimOut = AnimationUtils.loadAnimation(context, R.anim.menu_push_out);
layout.startAnimation(mAnimOut);
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) layout.getLayoutParams();
params.setMargins(0, 0, 0, 0);
layout.setLayoutParams(params);
}
}
二、首頁和側邊欄的製作
直接在畫一個Menu和真正要放內容的Content的Layout。
我的作法是直接把Menu壓在最底部,最上層再用一層ContentLayout蓋著它。
先來製作側邊欄。menu_main_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/holo_blue_bright"
tools:context="com.hello.kaiser.drawer.MenuMainLayout">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我是側邊欄"
android:textSize="50dp" />
</android.support.constraint.ConstraintLayout>
讓我們來寫menu_main_layout的java部分吧
MenuMainLayout.java
/**
* Menu內的東西可以實作在這裡
* */
public class MenuMainLayout extends RelativeLayout {
public MenuMainLayout(Context context) {
super(context);
View view = LayoutInflater.from(context).inflate(R.layout.menu_main_layout, this, false);
addView(view);
}
}
接著製作首頁內的內容,我是直接在頂端自己寫了ToolBar來呼叫側邊欄。
首頁內容
main_content_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
tools:context="com.hello.kaiser.drawer.MainContentLayout">
<include layout="@layout/activity_tool_bar" />
</RelativeLayout>
MainContentLayout.java/***
*
* 內容內的東西可以實作在這裏
*
* */
public class MainContentLayout extends RelativeLayout {
public MainContentLayout(Context context) {
super(context);
View view = LayoutInflater.from(context).inflate(R.layout.main_content_layout, this, false);
addView(view);
}
}
三、MainActivity程式的串接
接著來實作MainActivity吧,來到步驟的最後一步,把上面的東西全部串起來的MagicTime!MainActivity基本上就只是給一個id,我們要在上面疊入menu和主要content畫面
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.hello.kaiser.drawer.MainActivity">
</RelativeLayout>
MainActivity.javaimport android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.hello.kaiser.drawer.anim.MenuController;
public class MainActivity extends AppCompatActivity {
private RelativeLayout main_layout;
private int RealWidth = 0;
private TextView mMenuClick;//打開menu的效果
private boolean MenuOpen = false;//控制menu開啟與否
RelativeLayout mContent;//主要內容layout
RelativeLayout mBlack;//menu彈出的黑幕
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//獲取裝置的真正寬度
RealWidth = getResources().getDisplayMetrics().widthPixels;
initView();
initListener();
}
private void initView() {
main_layout = (RelativeLayout) findViewById(R.id.main_layout);
//側邊欄
MenuMainLayout mMenu = new MenuMainLayout(this);
//讓側邊欄開啟整個畫面的85%
main_layout.addView(mMenu, new RelativeLayout.LayoutParams(RealWidth * 85 / 100, ViewGroup.LayoutParams.MATCH_PARENT));
//主畫面內容
mContent = new MainContentLayout(this);
main_layout.addView(mContent, new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
//黑幕
mBlack = new RelativeLayout(this);
mContent.addView(mBlack, new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
mBlack.setBackgroundColor(0x7F000000);
mBlack.setVisibility(View.GONE);
mMenuClick = (TextView) mContent.findViewById(R.id.menu);
}
private void initListener() {
mBlack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
menuControl();
}
});
mMenuClick.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
menuControl();
}
});
}
private void menuControl() {
if (!MenuOpen) {
MenuOpen = true;
mBlack.setVisibility(View.VISIBLE);
MenuController.pushRight(this, mContent);
} else {
MenuOpen = false;
mBlack.setVisibility(View.GONE);
MenuController.pushLeft(this, mContent);
}
}
}
不講解什麼了,其實沒有很難,只是東西有點多,有問題再下發問囉。


沒有留言:
張貼留言