1. 程式人生 > >模仿QQ帶側邊欄框架搭建

模仿QQ帶側邊欄框架搭建

側邊欄實現的兩種方法

App展示:


方法一:SlidingMenu

https://github.com/jfeinstein10/SlidingMenu

在GitHub上下載SlidingMenu檔案,解壓後,將library庫匯入到AndroidStudio專案中

匯入方法

File--New--ImportModule--選擇解壓完的SlidingMenu檔案下的library資料夾--Finish

之後會報這樣一個錯:


你只需要找到Library的build.gradle,然後將buildeToolsVersion改為:

buildToolsVersion "19.1.0
之後會報這樣一個錯:


這個時候只需要點選安裝Build Tools 19.1.0版本即可。

之後就是關聯library庫,即:ModuleDependencies--選擇library庫即可。

接下來直接看程式碼(寫到比較low只是實現功能):

/**
 * 繼承SlidingFragmentActivity一定要將oncreate許可權改為public
 */
public class MainActivity extends SlidingFragmentActivity {

    @Override
public void onCreate(Bundle savedInstanceState) {
        super
.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //指定隱藏的佈局 setBehindContentView(R.layout.layout_slidingmenu); //獲取SlidingMenu物件 SlidingMenu slidingMenu = getSlidingMenu(); //指定開啟側邊欄後螢幕剩餘的空間 slidingMenu.setBehindOffset(300); //從左邊開啟側邊欄 slidingMenu.setMode
(SlidingMenu.LEFT); //設定全屏觸控模式 //slidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN); slidingMenu.setTouchModeAbove(SlidingMenu.LEFT); initFragment(); } //初始化Fragment private void initFragment() { FragmentManager fm = getSupportFragmentManager();//獲取Fragment管理器 FragmentTransaction ft = fm.beginTransaction();//開啟事務 ft.replace(R.id.flContent,new ContentFragment());//fragment動態替換幀佈局 ft.replace(R.id.flLeft,new LeftMenuFragment()); ft.commit(); //提交事務 } }
Fragment的基類:
public abstract class BaseFragment extends Fragment {

    public Activity mActivity; //Fragment的子類當做上下文使用
//BaseFragment例項物件建立的時候進行的回撥
//這個方法中一般用來獲取Fragment所依附的Activity物件
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mActivity = getActivity();
    }

    //返回Fragment所包裝的View物件
//一般用來載入佈局
@Nullable
    @Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return initView();
    }

    // Fragment所依附的Activity完全建立成功後進行的回撥
//一般用來載入資料
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        initData();
    }

    //基類無法決定子類的樣子,所以需要交給特定的子類完成佈局初始化
public abstract View initView();
    public void initData(){}
}
主內容的Fragment:
public class ContentFragment extends BaseFragment {

    private TextView  tvTitle;
    private ImageView iv;

    @Override
public View initView() {
        View view = View.inflate(mActivity, R.layout.layout_content, null);
        final ViewPager viewPager = (ViewPager) view.findViewById(R.id.viewpager);
        tvTitle = (TextView) view.findViewById(R.id.tvTitle);
        iv = (ImageView) view.findViewById(R.id.ivMenu);
        RadioGroup rg = (RadioGroup) view.findViewById(R.id.rg);
        rg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
                switch (checkedId) {
                    case R.id.rbConversation:
                        tvTitle.setText("訊息");
                        viewPager.setCurrentItem(0, false);
                        break;
                    case R.id.rbContact:
                        tvTitle.setText("聯絡人");
                        viewPager.setCurrentItem(1, false);
                        break;
                    case R.id.rbPlugin:
                        tvTitle.setText("動態");
                        viewPager.setCurrentItem(2, false);
                        break;
                }
            }
        });
        rg.check(R.id.rbConversation);  //預設選中會話頁
viewPager.setAdapter(new MyAdapter());

        return view;
    }

    //Fragment中的點選事件一定要在onActivityCreated方法呼叫後才能實現
@Override
public void initData() {
        iv.setOnClickListener(new View.OnClickListener() {
            @Override
public void onClick(View v) {
                MainActivity mainAcitivity = (MainActivity) mActivity;
                mainAcitivity.getSlidingMenu().toggle();
            }
        });
    }

    class MyAdapter extends PagerAdapter {

        @Override
public int getCount() {
            return 3;
        }

        @Override
public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

        @Override
public Object instantiateItem(ViewGroup container, int position) {
            //建立每一個itemview物件
switch (position) {
                case 0:
                    View conversationView = View.inflate(mActivity, R.layout.layout_conversation, null);
                    container.addView(conversationView);
                    return conversationView;
                case 1:
                    View contractView = View.inflate(mActivity, R.layout.layout_contract, null);
                    container.addView(contractView);
                    return contractView;
                case 2:
                    View pluginView = View.inflate(mActivity, R.layout.layout_plugin, null);
                    container.addView(pluginView);
                    return pluginView;
            }
            return super.instantiateItem(container, position);
        }

        @Override
public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
        }
    }
}
側邊欄的Fragment:
public class LeftMenuFragment extends BaseFragment {
    @Override
public View initView() {
        View view = View.inflate(mActivity, R.layout.layout_left, null);
        return view;
    }
}
禁止滑動的ViewPager:
public class NoScrollViewPager extends ViewPager {


    public NoScrollViewPager(Context context) {
        super(context);
    }

    public NoScrollViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
public boolean onTouchEvent(MotionEvent ev) {
        return true;
    }
}
方法二:使用DrawerLayout實現側邊欄

這個是系統自帶的,所以就直接上程式碼:

public class MainActivity extends AppCompatActivity {

    private Toolbar               mToolbar;
    private DrawerLayout          mDrawerLayout;
    private ActionBarDrawerToggle mDrawerToggle;

    @Override
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
        mToolbar = (Toolbar) findViewById(R.id.toolbar);
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerlayout);
        //設定ToolbarLogo
mToolbar.setLogo(R.mipmap.ic_launcher);
        //設定標題的margin
mToolbar.setTitleMarginStart(100);
        //設定Toolbar主標題
mToolbar.setTitle("主標題");
        //設定Toolbar副標題
mToolbar.setSubtitle("副標題");
        setSupportActionBar(mToolbar);

        //實現DrawerLayout開啟關閉監聽
mDrawerToggle = new ActionBarDrawerToggle(
                this, mDrawerLayout, mToolbar,
                R.string.open, R.string.close);
        mDrawerToggle.syncState();
        mDrawerLayout.addDrawerListener(mDrawerToggle);
        initFragment();
    }

    private void initFragment() {
        //獲取Fragment管理器
FragmentManager fm = getSupportFragmentManager();
        //開啟事務
FragmentTransaction ft = fm.beginTransaction();
        //替換幀佈局
ft.replace(R.id.flContent,new ContentFragment());
        ft.replace(R.id.flLeft,new LeftFragment());
        //提交事務
ft.commit();

    }
}

MAinActivity的佈局:

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
    <include layout="@layout/custom_toolbar"/>
    <include layout="@layout/custom_drawerlayout"/>
</LinearLayout>
Toolbar的佈局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#fff"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
>
</android.support.v7.widget.Toolbar>
DrawerLayout的佈局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawerlayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--內容介面-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
       <FrameLayout
android:id="@+id/flContent"
android:layout_width="match_parent"
android:layout_height="match_parent"></FrameLayout>
    </LinearLayout>
<!--側滑選單內容,必須指定其水平重力-->
<LinearLayout
android:layout_width="200dp"
android:layout_height="match_parent"
android:background="#00ff77"
android:layout_gravity="start"
android:orientation="vertical">
         <FrameLayout
android:id="@+id/flLeft"
android:layout_width="match_parent"
android:layout_height="match_parent"></FrameLayout>
    </LinearLayout>
</android.support.v4.widget.DrawerLayout>
注意:我在使用SlidingMenu的時候,點選每一頁使用的是ViewPager進行切換,這裡使用的是Fragment巢狀Fragment,效果一樣。(不過有點繁瑣,哈哈)

Fragment的基類:(標準程式碼,都是一樣的)。

public abstract class BaseFragment extends Fragment {

    public Activity mActivity;

    @Override
public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mActivity = getActivity();
    }

    @Nullable
    @Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return initView();
    }

    @Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
           initData();
    }

    public abstract View initView();
    public void initData(){};
}
主內容ContentFragment:

BottomNavigationBarGitHub路徑:

(https://github.com/Ashok-Varma/BottomNavigation)

public class ContentFragment extends BaseFragment implements BottomNavigationBar.OnTabSelectedListener {


    private BottomNavigationBar bottomBar;

    @Override
public View initView() {
        View view = View.inflate(mActivity, R.layout.fragment_content, null);
        bottomBar = (BottomNavigationBar) view.findViewById(R.id.bottomNavigationBar);
        //初始化BottomNavigationBar底部欄
initBottomBar();
        //初始化Fragment
initFragment();
        return view;
    }

    private void initFragment() {
        //Fragement巢狀Fragment必須使用getChildFragmentManager()獲取管理器
FragmentManager fm = getChildFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        ft.replace(R.id.fl_child_fragment, new ConversationFragment());
        ft.commit();
    }


    private void initBottomBar() {
        BadgeItem badgeItem = new BadgeItem(); //標記的item,也就是那個小圓點
badgeItem.setText("5")
                .setGravity(Gravity.RIGHT)  //靠右顯示
.setBackgroundColor(Color.RED)
                .setTextColor(Color.WHITE)
                .setHideOnSelect(false) //選中BottomNavigationBar時,不讓小圓點隱藏
.setAnimationDuration(100)
                .show();
        bottomBar
.setActiveColor("#00ACFF") //設定選中時的顏色
.setInActiveColor("#ABADBB")//設定為選中的顏色
.addItem(new BottomNavigationItem( //增加item
R.mipmap.conversation_selected_2, "訊息")
                        .setBadgeItem(badgeItem))
                .addItem(new BottomNavigationItem(R.mipmap.contact_selected_2, "聯絡人"))
                .addItem(new BottomNavigationItem(R.mipmap.plugin_selected_2, "動態"))
                .setFirstSelectedPosition(0)  //預設第0item被選中
.initialise(); //最後一步初始化完成
// BottomNavigationBar的點選事件
bottomBar.setTabSelectedListener(this);
    }

    @Override
public void onTabSelected(int position) {
        FragmentManager fm = getChildFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        switch (position) {
            case 0:
                ft.replace(R.id.fl_child_fragment, new ConversationFragment());
                ft.commit();
                break;
            case 1:
                ft.replace(R.id.fl_child_fragment, new ContactFragment());
                ft.commit();
                break;
            case 2:
                ft.replace(R.id.fl_child_fragment, new PluginFragment());
                ft.commit();
                break;
        }
    }

    @Override
public void onTabUnselected(int position) {

    }

    @Override
public void onTabReselected(int position) {

    }
}

側邊欄LeftFragment:(就簡單的顯示一個TextView)

public class LeftFragment extends BaseFragment {


    @Override
public View initView() {
        View view = View.inflate(mActivity, R.layout.fragment_left, null);
        return view;
    }
}
訊息ConversationFragment:(簡單的顯示一個TextView)
public class ConversationFragment extends BaseFragment {


    @Override
public View initView() {
        View view = View.inflate(mActivity, R.layout.fragment_conversation, null);
        return view;
    }
}
聯絡人ContactFragment:(簡單的顯示一個TextView)
public class ContactFragment extends BaseFragment {


    @Override
public View initView() {
        View view = View.inflate(mActivity, R.layout.fragment_contact, null);
        return view;
    }
}
動態PluginFragment:(簡單的顯示一個TextView)
public class PluginFragment extends BaseFragment {


    @Override
public View initView() {
        View view = View.inflate(mActivity, R.layout.fragment_plugin, null);
        return view;
    }
}