模仿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) {//创建每一个item的view对象 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) //默认第0个item被选中 .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;} }
模仿QQ带侧边栏框架搭建相关推荐
- iOS之UI--主流框架的搭建-- 仿制QQ的UI框架
iOS之UI--主流框架的搭建-- 仿制QQ的UI框架 使用XCode搭建多个控制器界面,一般在实际开发中建议超过四个控制器界面使用纯代码. 下面的实例其实已经超过了四个,总结详细步骤的目的,主要是更 ...
- 从0搭建一个Springboot+vue前后端分离项目(四)利用Element框架搭建页面主体部分表格与侧边栏
https://element-plus.gitee.io/zh-CN/component/menu.html 导航栏部分 选定menu菜单,选择竖型样式的 复制一下 <el-menudefau ...
- 模仿qq客户端应用源码且带安装包
这款源码案例是模仿qq客户端应用源码且带安装包,大家可以参考一下吧,也是比较完整的一款Android源码项目. 源码下载: http://code.662p.com/view/1931.html 00 ...
- Fdog系列(四):使用Qt框架模仿QQ实现登录界面,界面篇。
文章目录 一. 前言 二. 正文 1. 创建窗口,添加基本组件 2. 自定义标题,隐藏任务栏标题,实现系统托盘显示 3. 美化主界面,文本框的奇思妙想 4. 实现背景阴影 一. 前言 Fdog系列已写 ...
- GitHub上受欢迎的Android UI Library-项目开发实战篇:带各类框架链接地址详细解说及使用方法
这是我列举的下列所有框架github地址:https : //github.com/opendigg/awesome-github-android-ui 抽屉菜单类的框架 MaterialDrawer ...
- JAVA线程池管理及分布式HADOOP调度框架搭建
平时的开发中线程是个少不了的东西,比如tomcat里的servlet就是线程,没有线程我们如何提供多用户访问呢?不过很多刚开始接触线程的开发攻城师却在这个上面吃了不少苦头.怎么做一套简便的线程开发模式 ...
- 生信工作流框架搭建 | 02-nextflow 实战
目录 生信工作流框架搭建 | 02-nextflow 前情提要 开始使用 依赖 安装 核心概念 一个fastqc的示例,加深理解 快速搭建你的程序 你需要仔细阅读的: 可以快速浏览(但需要知道大概有什 ...
- Unity 游戏框架搭建 2019 (四十五) 独立的方法和独立的类
我们在开始本示例之前,先整理出我们当前库中的代码类型. 工具方法:CommonUtil.GameObjectSimplify等. 类: MonoBehaviourSimplify. 静态方法中的方法全 ...
- Unity 游戏框架搭建 2018 (一) 架构、框架与 QFramework 简介
约定 还记得上版本的第二十四篇的约定嘛?现在出来履行啦~ 为什么要重制? 之前写的专栏都是按照心情写的,在最初的时候笔者什么都不懂,而且文章的发布是按照很随性的一个顺序.结果就是说,大家都看完了,都还 ...
最新文章
- 银行卡大小的充电宝,买就送耳机!
- Hadoop的安装与配置及示例程序wordcount的运行
- Web开发(一)·期末不挂之第二章·HTML基础一(考试必考冷知识)
- java23种设计模式+单例_Java23种设计模式之单例模式
- Struts2中的Action
- Eclipse创建JavaWeb工程
- Oracle Buffer Cache的keep、recycle、default pool概念图解
- MyBatis 数据持久层
- ubuntu上安装 ibus Google拼音输入法
- 官宣!《花木兰》内地定档
- 【HTTPS运维神器】终于等到你!MySSL企业版重磅上线!
- 【转】Treeview 无限分类非递归终极解决方案
- 虚拟机是怎么实现的?(转)
- 程序员代码面试指南第二版 8.单调栈结构(普通及进阶)
- python爬虫实战万年历
- 怎样在两台计算机之间建立硬盘共享,如何让两台电脑硬盘共享在一起
- sql 财务科目余额表写法
- matlab solve和subs,【MATLAB】matlab中的subs()函数和solve()函数用法
- 雷鸣的游戏人生(七) --- 如何谈一场失败的恋爱?
- 如何设置lazada促销活动--Flash Sale