这篇文章为大家带来
1.官方BottomNavigationView的使用方法
2.结合ViewPager、Fragment实现一个流行UI布局!
3.并用反射解决ViewPager与BottomNavigationView侧滑联动时的一个小问题。
最终实现效果:
在谷歌官方发布BottomNavigationView控件之前我们可以自己组合控件实现,比如LinearLayout + TextView(使用android:drawableTop属性+selector状态切换)、RadioGroup + RadioButton等等组合控件的方法自定义实现复杂效果。除了第三方外,现在我们多了一个选择。
开始
1.新建project然后导入以下support:design library,BottomNavigationView就在这个design库中。顺带导入这个V4包,因为待会要使用到ViewPager(这里其实不用记这么麻烦的库跟版本怎么写,直接在AS 的design面板把控件拖进来就会自动导入了。)
compile’com.android.support:design:25.0.1’
compile’com.android.support:support-v4:25.0.1’
2.在res下新建menu文件夹,新建一个menu菜单
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_home"
android:title="首页"
android:icon="@drawable/home_selected"/>
<item
android:id="@+id/action_explore"
android:title="直播"
android:icon="@drawable/live"/>
<item
android:id="@+id/action_me"
android:title="关注"
android:icon="@drawable/follow"/>
<item
android:id="@+id/mfaxin"
android:title="发现"
android:icon="@drawable/video"/>
<item
android:id="@+id/mi"
android:title="我的"
android:icon="@drawable/user"/>
</menu>
3.接着是布局文件主要代码如下(最下面的View效果是加一个阴影):
<?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:orientation="vertical"
tools:context="com.example.myzg2.myapplication.MainActivity"
android:weightSum="1">
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="151dp"
android:layout_above="@+id/bottom_navigation" />
<android.support.design.widget.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:itemIconTint="@drawable/bottom_navigation_selector"
app:itemTextColor="@drawable/bottom_navigation_selector"
app:menu="@menu/menu_bottom_navigation" />
<View
android:layout_width="match_parent"
android:layout_height="0.1dp"
android:layout_above="@id/bottom_navigation"
android:background="#808080" />
</RelativeLayout>
app:itemIconTint=”@drawable/bottom_navigation_selector” 为icon着色,写个selector即可。
app:itemTextColor=”@drawable/bottom_navigation_selector”该属性为文字着色,同样写个selector实现点击颜色切换的效果
4.写完布局写代码,完整activity文件如下:
实例化控件后为NavigationView添加监听事件即可,代码如下:
package com.fedming.bottomnavigationdemo;
package com.example.myzg2.myapplication;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
public class MainActivity extends AppCompatActivity {
private ViewPager viewPager;
private MenuItem menuItem;
private BottomNavigationView bottomNavigationView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.viewpager);
bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottom_navigation);
//默认 >3 的选中效果会影响ViewPager的滑动切换时的效果,故利用反射去掉
BottomNavigationViewHelper.disableShiftMode(bottomNavigationView);
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.action_home:
viewPager.setCurrentItem(0);
break;
case R.id.action_explore:
viewPager.setCurrentItem(1);
break;
case R.id.action_me:
viewPager.setCurrentItem(2);
break;
case R.id.mfaxin:
viewPager.setCurrentItem(3);
break;
case R.id.mi:
viewPager.setCurrentItem(4);
break;
}
return false;
}
});
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
if (menuItem != null) {
menuItem.setChecked(false);
} else {
bottomNavigationView.getMenu().getItem(0).setChecked(false);
}
menuItem = bottomNavigationView.getMenu().getItem(position);
menuItem.setChecked(true);
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
//禁止ViewPager滑动
viewPager.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
setupViewPager(viewPager);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(BaseFragment.newInstance("首页"));
adapter.addFragment(BaseFragment.newInstance("直播"));
adapter.addFragment(BaseFragment.newInstance("关注"));
adapter.addFragment(BaseFragment.newInstance("发现"));
adapter.addFragment(BaseFragment.newInstance("我的s"));
viewPager.setAdapter(adapter);
}
}
可以看到BottomNavigationView+ViewPager+Fragment可以实现流行的布局框架,可以像微信那样左右滑动,也可以像支付宝那样点击切换。
禁止ViewPager滑动
如果不需要配置侧滑切换的话,直接默认效果就好,不要去反射修改了。禁止滑动时,为ViewPager添加setOnTouchListener接口,在onTouch下直接消费掉点击事件。添加下面这段代码:
viewPager.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
滑动时,ViewPager是切换过去了,下面这item也切换过去了,这种动画效果不需要时,创建一个BottomNavigationViewHelper
public class BottomNavigationViewHelper {
public static void disableShiftMode(BottomNavigationView navigationView) {
BottomNavigationMenuView menuView = (BottomNavigationMenuView) navigationView.getChildAt(0);
try {
Field shiftingMode = menuView.getClass().getDeclaredField("mShiftingMode");
shiftingMode.setAccessible(true);
shiftingMode.setBoolean(menuView, false);
shiftingMode.setAccessible(false);
for (int i = 0; i < menuView.getChildCount(); i++) {
BottomNavigationItemView itemView = (BottomNavigationItemView) menuView.getChildAt(i);
itemView.setShiftingMode(false);
itemView.setChecked(itemView.getItemData().isChecked());
}
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
在实例化BottomNavigationView后调用一次这行代码即可:
BottomNavigationViewHelper.disableShiftMode(bottomNavigationView);
BaseFragment.java
package com.example.myzg2.myapplication;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* Created by bruce on 2016/11/1.
* BaseFragment
*/
public class BaseFragment extends Fragment {
public static BaseFragment newInstance(String info) {
Bundle args = new Bundle();
BaseFragment fragment = new BaseFragment();
args.putString("info", info);
fragment.setArguments(args);
return fragment;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_base, null);
/*// TextView tvInfo = (TextView) view.findViewById(R.id.textView);
tvInfo.setText(getArguments().getString("info"));
tvInfo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Snackbar.make(v, "Don't click me.please!.", Snackbar.LENGTH_SHORT).show();
}
});*/
return view;
}
}
ViewPagerAdapter.java
package com.example.myzg2.myapplication;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import java.util.ArrayList;
import java.util.List;
/**
* Created by bruce on 2016/11/1.
* ViewPagerAdapter
*/
public class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment) {
mFragmentList.add(fragment);
}
}