版權聲明:本文爲HaiyuKing原創文章,轉載請註明出處!java
簡單實現側邊欄(側滑菜單)效果:android
此Demo只是簡單實現側邊欄的效果,目的在於能夠快速的導入到項目中。至於更復雜的效果,請閱讀《參考資料》git
注意事項:github
一、 導入類文件後須要change包名以及從新import R文件路徑網絡
二、 Values目錄下的文件(strings.xml、dimens.xml、colors.xml等),若是項目中存在,則複製裏面的內容,不要整個覆蓋app
在APP的build.gradle文件中添加如下代碼:ide
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
defaultConfig {
applicationId "com.why.project.drawerlayoutdemo"
minSdkVersion 16
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
//DrawerLayout側邊欄中動畫效果用到的 compile 'com.nineoldandroids:library:2.4.0'
}
<resources> <!-- Base application theme. --> <!--<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!– Customize your theme here. –> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> </style>--> <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> </style> </resources>
<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/id_drawerLayout" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- 主內容視圖必定要是DrawerLayout的第一個子視圖【必須】 --> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <!-- 引入導航欄 --> <include android:id="@+id/main_navbar" layout="@layout/navigationbar_main" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="內容區域" android:textSize="22sp" android:layout_gravity="center"/> </LinearLayout> <!-- 左側區域側邊欄【可選】【若是想要只有一個右側的側邊欄,那麼就只須要留一個便可,注意的是left須要換成right】 --> <!-- android:tag="LEFT"用於java代碼中經過drawerView.getTag()判斷左側仍是右側 --> <fragment android:id="@+id/fragment_leftmenu" android:name="com.why.project.drawerlayoutdemo.MainMenuLeftFragment" android:layout_width="300dp" android:layout_height="match_parent" android:layout_gravity="left" android:tag="LEFT" /> <!-- 右側區域側邊欄【可選】 --> <fragment android:id="@+id/fragment_rightmenu" android:name="com.why.project.drawerlayoutdemo.MainMenuRightFragment" android:layout_width="300dp" android:layout_height="match_parent" android:layout_gravity="right" android:tag="Right" /> </android.support.v4.widget.DrawerLayout>
<?xml version="1.0" encoding="utf-8"?> <!-- 首頁界面的導航欄佈局文件 --> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/nav_twoversion_home" android:layout_width="match_parent" android:layout_height="48dp" android:layout_gravity="center" android:background="#3F51B5" > <!-- 用戶側邊欄圖標 --> <ImageView android:id="@+id/nav_user" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:paddingLeft="10dp" android:paddingRight="10dp" android:contentDescription="@string/app_name" android:gravity="center" android:src="@drawable/nav_user" /> <!-- 標題 --> <TextView android:id="@+id/nav_title" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_centerInParent="true" android:gravity="center" android:text="@string/app_name" android:textColor="#ffffff" android:textSize="18sp" /> </RelativeLayout>
MainMenuLeftFragment.java函數
package com.why.project.drawerlayoutdemo; import android.os.Bundle; import android.support.v4.app.Fragment; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; /** * Created by HaiyuKing * Used 首頁左側側邊欄碎片界面 */ public class MainMenuLeftFragment extends Fragment { private static final String TAG = "MainMenuLeftFragment"; /**View實例*/ private View myView; // private TextView tv_show; //重寫 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Log.d(TAG,"onCreateView"); myView = inflater.inflate(R.layout.fragment_home_left_menu, container, false); return myView; } @Override public void onActivityCreated(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onActivityCreated(savedInstanceState); Log.d(TAG,"onActivityCreated"); //初始化控件以及設置 initView(); } @Override public void onResume() { super.onResume(); Log.d(TAG,"onResume"); //初始化監聽事件 initEvent(); } /**初始化控件*/ private void initView(){ Log.d(TAG,"initView"); tv_show = myView.findViewById(R.id.tv_show); } /**初始化默認數據【這個須要在activity中執行,緣由是:在佈局文件中經過<fragment>的方式引用Fragment,打開Activity的時候,Fragment的生命週期函數均執行了】 * 那麼就存在一個問題,初始化fragment中的數據,可能會在activity數據初始化以前執行*/ public void setDefaultDatas(){ tv_show.setText(tv_show.getText() + "\n執行了一次setDefaultDatas()"); } /**初始化監聽事件*/ private void initEvent(){ } }
fragment_home_left_menu.xml佈局文件佈局
<?xml version="1.0" encoding="utf-8"?> <!-- 首頁界面的左側側邊欄界面佈局文件 --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="#E3E3E3"> <TextView android:id="@+id/tv_show" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="左側側邊欄區域" android:textSize="18sp" /> </LinearLayout>
package com.why.project.drawerlayoutdemo; import android.content.Context; import android.os.Bundle; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.Gravity; import android.view.View; import android.widget.ImageView; import com.nineoldandroids.view.ViewHelper; public class MainActivity extends AppCompatActivity { private Context mContext; /**導航欄左側的用戶圖標*/ private ImageView nav_userImg; /**導航欄左側的側邊欄的父容器*/ private DrawerLayout mDrawerLayout; /**導航欄左側的側邊欄碎片界面*/ private MainMenuLeftFragment leftMenuFragment; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mContext = this; //初始化控件 initViews(); //初始化數據 initData(); //初始化控件的點擊事件 initEvent(); } private void initViews() { nav_userImg = (ImageView) findViewById(R.id.nav_user); mDrawerLayout = (DrawerLayout) findViewById(R.id.id_drawerLayout); //關閉手勢滑動:DrawerLayout.LOCK_MODE_LOCKED_CLOSED(Gravity.LEFT:表明左側的) mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED, Gravity.LEFT); leftMenuFragment = (MainMenuLeftFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_leftmenu); } private void initData() { } private void initEvent() { //用戶圖標的點擊事件 nav_userImg.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { OpenLeftMenu(); } }); //側邊欄的事件監聽 mDrawerLayout.addDrawerListener(new DrawerLayout.DrawerListener() { /** * 當抽屜滑動狀態改變的時候被調用 * 狀態值是STATE_IDLE(閒置-0),STATE_DRAGGING(拖拽-1),STATE_SETTLING(固定-2)中之一。 */ @Override public void onDrawerStateChanged(int newState) { } /** * 當抽屜被滑動的時候調用此方法 * slideOffset 表示 滑動的幅度(0-1) */ @Override public void onDrawerSlide(View drawerView, float slideOffset) { Log.w("onDrawerSlide", "slideOffset="+slideOffset);//0.0 -- 0.56 -- 1.0 View mContent = mDrawerLayout.getChildAt(0);//內容區域view View mMenu = drawerView; float scale = 1 - slideOffset; if (drawerView.getTag().equals("LEFT")) {//左側的側邊欄動畫效果 //設置左側區域的透明度0.6f + 0.4f * (0.0 ... 1.0)【也就是打開的時候透明度從0.6f ... 1.0f,關閉的時候反之】 ViewHelper.setAlpha(mMenu, 0.6f + 0.4f * slideOffset); //移動內容區域:左側側邊欄寬度 * (0.0 ... 1.0)【也就是打開的時候,內容區域移動從0 ... 左側側邊欄寬度】 ViewHelper.setTranslationX(mContent,mMenu.getMeasuredWidth() * slideOffset); mContent.invalidate();//重繪view } else {//右側的側邊欄動畫效果 //移動內容區域:-右側側邊欄寬度 * (0.0 ... 1.0)【也就是打開的時候,內容區域移動從-0 ... -左側側邊欄寬度】 ViewHelper.setTranslationX(mContent,-mMenu.getMeasuredWidth() * slideOffset); mContent.invalidate(); } } /** * 當一個抽屜被徹底打開的時候被調用 */ @Override public void onDrawerOpened(View drawerView) { if (drawerView.getTag().equals("LEFT")){//若是感受顯示有延遲的話,能夠放到nav_userImg的點擊事件監聽中執行 leftMenuFragment.setDefaultDatas();//打開的時候初始化默認數據【好比:請求網絡,獲取數據】 } } /** * 當一個抽屜被徹底關閉的時候被調用 */ @Override public void onDrawerClosed(View drawerView) { //關閉手勢滑動:DrawerLayout.LOCK_MODE_LOCKED_CLOSED(Gravity.LEFT:表明左側的) mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED, Gravity.LEFT); } }); } /**打開左側的側邊欄*/ public void OpenLeftMenu() { mDrawerLayout.openDrawer(Gravity.LEFT); //打開手勢滑動:DrawerLayout.LOCK_MODE_UNLOCKED(Gravity.LEFT:表明左側的) mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED,Gravity.LEFT); } }
無gradle
Android DrawerLayout 高仿QQ5.2雙向側滑菜單