新项目一之常见项目框架搭建

正好一个新项目刚刚开始,就写一下新项目的框架搭建。以后开新项目的时候就可以直接搬砖了,加快开发的效率。
项目的框架如下,使用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中把AppThemeparent也改一下,不改的话偶尔会出现程序页面上还是有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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值