Home

smartbeng

做好今天的自己!

Blog About Email Github

2017-04-15
TabLayout + ViewPager 实现微信主页面切换效果

因为项目类型缘故,好久没做类似功能了,因此接下来准备开始一个「温习」系列,将之前掌握的技术点认真记录下来,避免生疏。过程中一定会细心将每个点分享出来,态度决定决定「高度」!

Android Studio 中将 Gradle 配置统一化

相信刚开始接触 As 或者使用了一段时间的同学们,并不一定会掌握这个点。我们通常在项目开发中经常会遇到的一个问题,因为 AS 版本不同导致项目在导入时频繁改动 Gradle 配置,当然还有其他因素造成我们会时常对配置文件做修改,所以今天姑且将这套「配置规范」贴出来!

首先是项目根目录的 build.gradle 文件:

ext {
// 配置项目基础信息
config = [
package : "cn.kgc.life",
buildToolsVersion: "25.0.1",
compileVersion : 24,
minSdk : 15,
targetSdk : 24,
versionCode : 1,
versionName : "1.0",
]
// 配置项目依赖 jar 的版本
lib = [
supportVersion: "24.2.1",
gson : "2.4",
butterknife : "8.5.1",
]
}
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.2'
classpath 'com.jakewharton:butterknife-gradle-plugin:8.5.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}

其次是 app 下的 build.gradle 配置:

apply plugin: 'com.android.application'
def cfg = rootProject.ext.config // 配置
def libs = rootProject.ext.lib // 库
android {
compileSdkVersion cfg.compileVersion
buildToolsVersion cfg.buildToolsVersion
defaultConfig {
applicationId cfg.package
minSdkVersion cfg.minSdk
targetSdkVersion cfg.targetSdk
versionCode cfg.versionCode
versionName cfg.versionName
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
//根据需求选择要加载的依赖包 以下只是我的需求
compile fileTree(include: ['*.jar'], dir: 'libs')
compile "com.android.support:appcompat-v7:${libs.supportVersion}"
compile "com.android.support:design:${libs.supportVersion}"
compile "com.android.support:support-v4:${libs.supportVersion}"
compile 'com.jakewharton:butterknife:8.5.1'
compile 'com.android.support:support-v4:24.2.1'
testCompile 'junit:junit:4.12'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1'
}

根目录下Gradle 下的 gradle-wrapper.properties 文件:

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
## 注意下面这个 gradle-2.14.1 是新建项目就有的 版本号跟 AS 版本相对应
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip

新建项目开始布局

  • MainActivity 布局:
<!-- ViewPager 空间是一个容器,用来装载后面的fragment布局 -->
<android.support.v4.view.ViewPager
android:id="@+id/vp_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/main_toolbar"
android:layout_alignParentStart="true" />
<!-- tabIndicatorColor 指示器颜色 -->
<!-- tabIndicatorHeight 指示器高度 -->
<!-- tabSelectedTextColor 选中tab 的颜色 -->
<!-- tabTextColor 没有选中的颜色 -->
<!-- tabGravity 设置填充模式 -->
<!-- tabMode 设置是否可以滑动 -->
<android.support.design.widget.TabLayout
android:id="@+id/tab_bottom_container"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
android:layout_alignParentBottom="true"
app:tabIndicatorHeight="0dp"
app:tabMode="fixed"
android:background="@android:color/white"
app:tabTextColor="@android:color/black" />
<!-- TabLayout 用于在下方点击的导航栏 -->

注意这两个空间需要添加 Design 和 V4 依赖

  • 加入 fragment

    每一个可滑动也可点击切换的页面都是一个fragment

    所以我们需要新建三个 fragment

<!-- 在 android studio 中 new 出三个带布局的 fragment -->
<!-- 一个页面就是一个 fragment ,在 fragment 的布局中添加需求布局 -->
<!-- 在每一个 fragment 中做如下修改 -->
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_more, container, false);
//将每一个 fragment 的布局当做 view 返回展示到住页面上
return view;
}
  • MainActivity 中实现功能
  • 开始之前我们先将底部导航栏(TabLayou)所需的 menu 资源准备好

    <!-- 在 res 下新建一个 Menu 文件夹 -->
    <!-- 然后创建一个名为 menu_bottom_nav 的布局 内容如下 -->
    <!-- 以下的 drawable 下的图片和图片选择器自行配置 -->
    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
    android:icon="@drawable/btn_home_selector"
    android:title="@string/action_home" />
    <item
    android:icon="@drawable/btn_conv_selector"
    android:title="@string/action_conv" />
    <item
    android:icon="@drawable/btn_more_selector"
    android:title="更多" />
    </menu>
  • 以下的解释全在代码中用注释的方式,便于一目了然!

public class BottomNavScrollActivity extends AppCompatActivity {
/**
* 1. 创建 ViewPager 组件
* 2. 构造数据源与适配器
* 3. 将适配器和 ViewPager 进行关联
*/
private ViewPager mViewPager;
private TabLayout mTabLayout;
/**
* 存储底部导航数据源
*/
private Menu mNavMenu;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bottom_nav_scroll);
mViewPager = (ViewPager) findViewById(R.id.vp_container);
mTabLayout = (TabLayout) findViewById(R.id.tab_top_container);
// 创建menu对象
mNavMenu = new MenuBuilder(this);
// 将menu文件加载到menu对象
getMenuInflater().inflate(R.menu.menu_bottom_nav, mNavMenu);
// 获取父类提供的fragment管理对象
FragmentManager fragmentManager = getSupportFragmentManager();
// 将适配器和 ViewPager 进行关联
mViewPager.setAdapter(new MyAdapter(fragmentManager));
// 将TabLayout 和ViewPager 关联
mTabLayout.setupWithViewPager(mViewPager);
for (int i = 0; i < mTabLayout.getTabCount(); i++) {
// 循环获取每一个tab对象
TabLayout.Tab tab = mTabLayout.getTabAt(i);
// 获取每一个menu中存储的数据
MenuItem item = mNavMenu.getItem(i);
// 设置每一个tab显示的文本
tab.setText(item.getTitle());
tab.setIcon(item.getIcon());
}
}
//创建适配器
class MyAdapter extends FragmentPagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new HomeFragment();
case 1:
return new ConvFragment();
case 2:
return new MoreFragment();
}
return null;
}
//返回底部菜单的数量
@Override
public int getCount() {
return mNavMenu.size();
}
}
}

这样就实现了微信主页面(仅限于 Android)的效果,可点击底部导航栏,也可左右滑动切换页面的效果!

微信公众号「smartbeng」,吐血版珍藏持续更新,一个会爱上的公众号。

webwxgetmsgimg.jpg


smartbeng

scribble

Blog About Email Github