正好一个新项目刚刚开始,就写一下新项目的框架搭建。以后开新项目的时候就可以直接搬砖了,加快开发的效率。
项目的框架如下,使用viewpager+TabLayout进行项目框架的构建。
一、引入三方库
新建项目后第一步就是引入我们需要使用的三方库
使用AS新建项目后build.gradle文件的三方库引入如下:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.3.1'
testCompile 'junit:junit:4.12'
}
然后我们引入开发需要的库,首先我们引入设计支持库和V4包
compile 'com.android.support:design:25.3.1'
compile 'com.android.support:support-v4:25.3.1'
联网请求框架retrofit
三件套
compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta3'
当然butterknife
也是必须引入,因为可以一键findviewbyid嘛
compile 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
接下来就是解析json数据常用的gson,当然你也可以引入其他的库,但是gson毕竟谷歌亲儿子,这里我还是使用gson的
compile 'com.google.code.gson:gson:2.5'
最后还有我比较喜欢的图像处理库Glide,同时还有Glide的辅助库,用来设置一些圆角图什么的,还是很方便的哟
compile 'com.github.bumptech.glide:glide:3.7.0'
compile 'jp.wasabeef:glide-transformations:1.0.6' //Glide图像转换
最后我们引入需要的三方库后dependencies
就成这样了
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
//---项目导入三方库
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support:design:25.3.1'
compile 'com.android.support:support-v4:25.3.1'
compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta3'
compile 'com.jakewharton:butterknife:8.8.1'
compile 'com.google.code.gson:gson:2.5'
compile 'com.github.bumptech.glide:glide:3.7.0'
compile 'jp.wasabeef:glide-transformations:1.0.6' //Glide圆形图转换
testCompile 'junit:junit:4.12'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
}
二、程序样式
俗话说,人靠衣装佛靠金装,我们的程序也是需要注意一下形象的嘛!来在清单文件中整整容
首先我们改一下程序的主题样式换成Theme.AppCompat.Light.NoActionBar
,
并且在res
->values
->styles.xml
中把AppTheme
的parent
也改一下,不改的话偶尔会出现程序页面上还是有ActionBar
的情况,所以我一般都是改一下,如下:
<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>
然后改一下app_name
,在res
->values
->strings.xml
中修改
<string name="app_name">程序名称</string>
再换一下应用图标icon
,这样前期整容工作基本上就做完了,整完容后的清单文件长这样:
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.AppCompat.Light.NoActionBar">
<activity android:name=".home.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
三、搭框架
1、在main_layout中放入viewpager和TabLayout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.cnbs.managescience_gk.home.MainActivity">
<com.cnbs.managescience_gk.view.viewpager.ControlledViewPager
android:id="@+id/main_vp"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<android.support.design.widget.TabLayout
android:id="@+id/main_tabLayout"
android:layout_width="match_parent"
android:layout_height="45dp"
android:background="@color/colorPrimaryDark"
app:tabGravity="fill"
app:tabIndicatorHeight="0px"
app:tabMode="fixed" />
</LinearLayout>
这里用到了设计支持库的TabLayout
和自定义的可以控制是否滑动的ViewPager
—-ControlledViewPager
/**
* 可控制是否滑动的ViewPager
* @author zuo
* @date 2017/10/23 18:27
*/
public class ControlledViewPager extends ViewPager {
private boolean noScroll = true; //是否不让滑动,true为禁止滑动
public ControlledViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public ControlledViewPager(Context context) {
super(context);
}
public void setNoScroll(boolean noScroll) {
this.noScroll = noScroll;
}
@Override
public void scrollTo(int x, int y) {
super.scrollTo(x, y);
}
@Override
public boolean onTouchEvent(MotionEvent arg0) {
/* return false;//super.onTouchEvent(arg0); */
if (noScroll)
return false;
else
return super.onTouchEvent(arg0);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent arg0) {
if (noScroll)
return false;
else
return super.onInterceptTouchEvent(arg0);
}
@Override
public void setCurrentItem(int item, boolean smoothScroll) {
super.setCurrentItem(item, smoothScroll);
}
@Override
public void setCurrentItem(int item) {
super.setCurrentItem(item,false); //false---表示切换的时候,不需要切换时间
}
}
2、设置TabLayout内部item的布局
先上tab_main_item.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:paddingTop="2dp"
android:paddingBottom="2dp"
android:gravity="center_horizontal"
android:orientation="vertical">
<ImageView
android:id="@+id/main_tab_img"
android:layout_width="20dp"
android:layout_height="18dp"
android:src="@mipmap/ic_launcher"/>
<TextView
android:id="@+id/main_tab_tv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:lines="1"
android:text="@string/main_tab0"
android:textColor="@drawable/selector_main_tab_text_color"
android:textSize="12sp" />
</LinearLayout>
我们注意到了tab中的TextView
有一个文字选择器,其实ImageView
也有选择器,只是ImageView
的选择器是在代码中设置的,附上文字选择器selector_main_tab_text_color
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Non focused states -->
<item android:color="@color/colorGray" android:state_focused="false" android:state_pressed="false" android:state_selected="false"/>
<item android:color="@color/base_color" android:state_focused="false" android:state_pressed="false" android:state_selected="true"/>
<!-- Focused states -->
<item android:color="@color/colorGray" android:state_focused="true" android:state_pressed="false" android:state_selected="false"/>
<item android:color="@color/base_color" android:state_focused="true" android:state_pressed="false" android:state_selected="true"/>
<!-- Pressed -->
<item android:color="@color/base_color" android:state_pressed="true"/>
</selector>
图片选择器selector_main_home_tab
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/img_normal" android:state_selected="false"/>
<item android:drawable="@drawable/img_selected" android:state_selected="true"/>
</selector>
3、viewpager适配器
TabLayout的item都准备好了,但是viewpager的item还没有准备好,so,我们来建一个viewpager适配器MainFragmentAdapter
,因为只是演示,所以我这里只建了一个Fragment和一个tab图标选择器(其实是我懒)
/**
*
* @author zuo
* @date 2017/10/23 16:38
*/
public class MainFragmentAdapter extends FragmentPagerAdapter {
private Context context;
private String[] mTitles = new String[]{"首页", "任务管理", "通知管理", "通讯录", "问题反馈"};
public MainFragmentAdapter(FragmentManager fm, Context context) {
super(fm);
this.context = context;
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return HomeFragment.newInstance();
case 1:
return HomeFragment.newInstance();
case 2:
return HomeFragment.newInstance();
case 3:
return HomeFragment.newInstance();
case 4:
return HomeFragment.newInstance();
default:
return HomeFragment.newInstance();
}
}
@Override
public int getItemPosition(Object object) {
return POSITION_UNCHANGED;
}
@Override
public int getCount() {
return mTitles.length;
}
//ViewPager与TabLayout绑定后,这里获取到PageTitle就是Tab的Text
@Override
public CharSequence getPageTitle(int position) {
return mTitles[position];
}
private int[] imageResId = {R.drawable.selector_main_home_tab, R.drawable.selector_main_home_tab, R.drawable.selector_main_home_tab,
R.drawable.selector_main_home_tab, R.drawable.selector_main_home_tab};
public View getTabView(int position) {
View v = LayoutInflater.from(context).inflate(R.layout.tab_main_item, null);
TextView tv = (TextView) v.findViewById(R.id.main_tab_tv);
tv.setText(mTitles[position]);
ImageView img = (ImageView) v.findViewById(R.id.main_tab_img);
img.setImageResource(imageResId[position]);
return v;
}
}
viewpager的itemHomeFragment
,改写之后的代码如下
/**
*
* @author zuo
* @date 2017/10/23 19:00
*/
public class HomeFragment extends Fragment {
public static HomeFragment newInstance() {
Bundle args = new Bundle();
HomeFragment fragment = new HomeFragment();
fragment.setArguments(args);
return fragment;
}
@SuppressLint("ValidFragment")
public HomeFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
if (view == null) {
view = inflater.inflate(R.layout.fragment_home, container, false);
ButterKnife.bind(this, view);
}
return view;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
initView();
}
}
4、将viewpager和TabLayout关联起来
将viewpager和TabLayout关联起来之后我们的框架就搭完了,剩下的就是舔砖加瓦(具体功能实现)了,MainActivtiy
代码
/**
* @author zuo
* @date 2017/10/23 16:17
*/
public class MainActivity extends BaseActivity {
@BindView(R.id.main_vp)
ViewPager mainVp;
@BindView(R.id.main_tabLayout)
TabLayout mainTabLayout;
@BindView(R.id.activity_main)
LinearLayout activityMain;
private MainFragmentAdapter mainFragmentAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
initView();
}
private void initView() {
mainFragmentAdapter = new MainFragmentAdapter(getSupportFragmentManager(), MainActivity.this);
mainVp.setAdapter(mainFragmentAdapter);
//将TabLayout与ViewPager绑定在一起
mainTabLayout.setupWithViewPager(mainVp);
for (int i = 0; i < mainTabLayout.getTabCount(); i++) {
TabLayout.Tab tab = mainTabLayout.getTabAt(i);
//设置要用于对应tab的自定义视图。
if (tab != null) {
tab.setCustomView(mainFragmentAdapter.getTabView(i));
}
}
mainVp.setCurrentItem(1);
mainVp.setCurrentItem(0);
}
}
四、补充
想了想,好像没了,那就这样了,框架到这里就搭完了O(∩_∩)O