• 安卓开发笔记——打造属于自己的博客园APP(一)


      最近事情比较多,博客更新又落下了,平时有个习惯,喜欢睡前看看博客园里博友的文章,但一直感觉APP市场上下载下来的博客园客户端用起来并不是很舒服,近来发现博客园也有对外开放的数据接口,所以打算自己写个博客园的客户端。

      近来谷歌推出了一套全新的UI设计规范——Material Design,不清楚的朋友看看《Material design非官方中文指导手册》,相比之前谷歌在Android Holo风格上平平淡淡的表现不同,Material Design现在是被Google所比较重视的。在推出这门全新设计语言后,谷歌上自家的应用很快就使用Material Design全新设计了,如Play商店,Google Map,Google+等等。

      打算赶一下潮流,紧跟谷歌的步伐遵循Material Design设计规范开发这个APP,也刚好让自己熟悉下Android5.0后的新特性。这个APP会慢慢做下来,逐步完善所需功能,我也不确定会写几篇文章,反正有空闲的时候就拿出来写写吧。

      初步打算实现用户的登陆,分类查看文章内容,新闻内容,包括用户信息的浏览,关注,偏好文章的收藏以及离线阅读功能,大家如果有什么好的建议,可以在文章评论给我留言,虚心请教。

    好了,言归正传,先来看下今天要实现的效果:(UI主框架的搭建)

    如果在过去,我们要实现上图的效果,顶部菜单我们会使用ActionBar,侧滑菜单我们会使用SlidingMenu,ViewPager滑动页面指示器我们会使用ViewPagerIndicator或者PagerSlidingTabStrip等开源控件。但现在谷歌官方已经给我们提供了实现,我们当然就用官方提供的控件了。

    侧滑菜单的实现:DrawerLayout  ViewPager滑动页面指示器的实现:TabLayout  这2个空间分别是在V4包和V7包中,不熟悉的朋友,网上自己查查资料吧。

    关于代码实现:

    顶部为ToolBar,侧滑菜单为DrawerLayout,侧滑菜单内容为NavigationView,主界面为ViewPager内嵌Fragment,直接看代码吧。

    首先我们需要对风格进行定义,我们的顶部不再实现ActionBar,而是谷歌新推出的基于ActionBar实现的ToolBar(在V7支持包下):

     1 <resources>
     2     <!-- Base application theme. -->
     3     <style name="AppBaseTheme" parent="Theme.AppCompat.Light.NoActionBar">
     4         <!-- Toolbar(actionbar)颜色 -->
     5         <item name="colorPrimary">@color/md_green_600</item>
     6         <!-- 状态栏颜色 -->
     7         <item name="colorPrimaryDark">@color/md_green_800</item>
     8         <!-- 窗口的背景颜色 -->
     9         <item name="android:windowBackground">@android:color/white</item>
    10         <!-- SearchView -->
    11         <item name="searchViewStyle">@style/MySearchViewStyle</item>
    12     </style>
    13 
    14     <style name="MySearchViewStyle" parent="Widget.AppCompat.SearchView" />
    15 
    16     <style name="AppTheme" parent="@style/AppBaseTheme" />
    17 </resources>

    然后关于底部的NavigationBar,我们需要额外的在values-v21文件内添加:

    1 <resources xmlns:android="http://schemas.android.com/apk/res/android">
    2 
    3     <style name="AppTheme" parent="@style/AppBaseTheme">
    4         <!-- 底部导航栏颜色 -->
    5         <item name="android:navigationBarColor">@color/md_green_600</item>
    6     </style>
    7 
    8 </resources>

    再来看下布局文件:

    主布局文件:activity_main.xml

     1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     android:layout_width="match_parent"
     3     android:layout_height="match_parent"
     4     android:orientation="vertical">
     5     <!--ToolBar-->
     6     <include layout="@layout/activity_toolbar" />
     7     <!--DrawerLayout-->
     8     <android.support.v4.widget.DrawerLayout
     9         android:id="@+id/dl_drawer"
    10         android:layout_width="match_parent"
    11         android:layout_height="match_parent">
    12         <!--Main Content-->
    13         <include layout="@layout/activity_main_content" />
    14         <!--Main Menu-->
    15         <include layout="@layout/activity_main_menu" />
    16     </android.support.v4.widget.DrawerLayout>
    17 
    18 </LinearLayout>

    ToolBar布局文件:activity_toolbar.xml

    1 <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    2     xmlns:app="http://schemas.android.com/apk/res-auto"
    3     android:id="@+id/activity_toolbar"
    4     android:layout_width="match_parent"
    5     android:layout_height="?attr/actionBarSize"
    6     android:background="@color/md_green_600"
    7     android:theme="@style/ThemeOverlay.AppCompat.Dark"
    8     app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

    侧滑菜单布局文件:activity_main_menu.xml,activity_main_menu_header.xml

     1 <android.support.design.widget.NavigationView
     2     xmlns:android = "http://schemas.android.com/apk/res/android"
     3     xmlns:app = "http://schemas.android.com/apk/res-auto"
     4     android:id = "@+id/nv_main_menu"
     5     android:layout_height = "match_parent"
     6     android:layout_width = "wrap_content"
     7     android:layout_gravity = "start"
     8     android:clickable="true"
     9     app:headerLayout = "@layout/activity_main_menu_header"
    10     app:menu = "@menu/menu_drawer_view"/>  

     1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     xmlns:app="http://schemas.android.com/apk/res-auto"
     3     android:layout_width="match_parent"
     4     android:layout_height="200dp"
     5     android:background="@drawable/menu_header_bg"
     6     android:orientation="vertical"
     7     android:theme = "@style/ThemeOverlay.AppCompat.Dark"
     8     android:padding="30dp">
     9 
    10 
    11     <com.makeramen.roundedimageview.RoundedImageView
    12         android:id="@+id/imageView1"
    13         android:layout_width="100dp"
    14         android:layout_height="100dp"
    15         android:src="@mipmap/avatar_default"
    16         app:riv_border_color="#00ffffff"
    17         app:riv_border_width="2dip"
    18         app:riv_corner_radius="30dip"
    19         app:riv_mutate_background="true"
    20         app:riv_oval="true"
    21         app:riv_tile_mode="repeat" />
    22 
    23     <TextView
    24         android:layout_width="wrap_content"
    25         android:layout_height="wrap_content"
    26         android:layout_marginTop="16dp"
    27         android:layout_marginLeft="16dp"
    28         android:layout_marginStart="16dp"
    29         android:text="未登录用户"
    30         android:textAppearance="@style/TextAppearance.AppCompat.Body2"/>
    31 
    32 </LinearLayout>

    菜单内容文件:menu_drawer_view.xml(menu文件夹下)

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <menu xmlns:android="http://schemas.android.com/apk/res/android">
     3 
     4     <group android:checkableBehavior="single">
     5         <item
     6             android:id="@+id/nav_home"
     7             android:icon="@mipmap/ic_home_black_48dp"
     8             android:title="主页" />
     9         <item
    10             android:id="@+id/nav_sort"
    11             android:icon="@mipmap/ic_assignment_black_48dp"
    12             android:title="分类" />
    13         <item
    14             android:id="@+id/nav_rss"
    15             android:icon="@mipmap/ic_favorite_black_48dp"
    16             android:title="订阅" />
    17         <item
    18             android:id="@+id/nav_like"
    19             android:icon="@mipmap/ic_grade_black_48dp"
    20             android:title="收藏" />
    21     </group>
    22 
    23     <item android:title="其他">
    24         <menu>
    25             <item
    26                 android:id="@+id/nav_setting"
    27                 android:icon="@mipmap/ic_settings_black_48dp"
    28                 android:title="设置"></item>
    29             <item
    30                 android:id="@+id/nav_help"
    31                 android:icon="@mipmap/ic_help_black_48dp"
    32                 android:title="帮助"></item>
    33         </menu>
    34     </item>
    35 
    36 </menu>

    主内容布局文件:activity_main_content.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <android.support.design.widget.TabLayout
            android:id="@+id/tl_main_tabs"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:background="@color/md_green_600"
            app:elevation="5dp"
            app:tabIndicatorColor="@color/md_green_800"
            app:tabSelectedTextColor="@color/md_white_1000"
            app:tabTextColor="@color/md_green_100" />
    
        <android.support.v4.view.ViewPager
            android:id="@+id/vp_main_content"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </LinearLayout>

    再来看下JAVA代码:

    主Activity:

    package com.lcw.rabbit.myblog;
    
    import android.os.Bundle;
    import android.support.design.widget.NavigationView;
    import android.support.design.widget.TabLayout;
    import android.support.v4.app.Fragment;
    import android.support.v4.view.ViewPager;
    import android.support.v4.widget.DrawerLayout;
    import android.support.v7.app.ActionBarDrawerToggle;
    import android.support.v7.app.AppCompatActivity;
    import android.support.v7.widget.Toolbar;
    import android.view.Menu;
    import android.view.MenuItem;
    
    import com.lcw.rabbit.myblog.adapter.ViewPagerAdapter;
    import com.lcw.rabbit.myblog.fragment.BestFragment;
    import com.lcw.rabbit.myblog.fragment.CandidateFragment;
    import com.lcw.rabbit.myblog.fragment.HomeFragment;
    import com.lcw.rabbit.myblog.fragment.RecommendFragment;
    
    public class MainActivity extends AppCompatActivity {
    
        private Toolbar mToolbar;
        private DrawerLayout mDrawerLayout;
        private NavigationView mNavigationView;
        private TabLayout mTabLayout;
        private ViewPager mViewPager;
        private ActionBarDrawerToggle mActionBarDrawerToggle;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initView();
        }
    
        /**
         * 初始化布局
         */
        private void initView() {
            //实例化控件
            mToolbar = (Toolbar) findViewById(R.id.activity_toolbar);
            mDrawerLayout = (DrawerLayout) findViewById(R.id.dl_drawer);
            mTabLayout = (TabLayout) findViewById(R.id.tl_main_tabs);
            mNavigationView = (NavigationView) findViewById(R.id.nv_main_menu);
            mViewPager = (ViewPager) findViewById(R.id.vp_main_content);
            //设置对应属性
            initToolBar();
            initMainContent();
            initAction();
    
    
        }
    
        /**
         * 初始化控件的动作监听
         */
        private void initAction() {
            //设置侧滑菜单点击监听
            mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
                @Override
                public boolean onNavigationItemSelected(MenuItem menuItem) {
                    int id = menuItem.getItemId();
                    switch (id) {
                        //返回首页
                        case R.id.nav_home:
                            mViewPager.setCurrentItem(0);
                            break;
                    }
                    mDrawerLayout.closeDrawers();
                    return false;
                }
            });
        }
    
        /**
         * 初始化TabLayout和ViewPager
         */
        private void initMainContent() {
            ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
            Fragment homeFragment = new HomeFragment();
            Fragment bestFragment = new BestFragment();
            Fragment candidateFragment = new CandidateFragment();
            Fragment recommendFragment = new RecommendFragment();
            adapter.addFragment(homeFragment, "首页");
            adapter.addFragment(bestFragment, "精华");
            adapter.addFragment(candidateFragment, "候选");
            adapter.addFragment(recommendFragment, "推荐");
            mViewPager.setAdapter(adapter);
            mTabLayout.setupWithViewPager(mViewPager);
        }
    
        /**
         * 初始化ToolBar
         */
        private void initToolBar() {
            mToolbar.setTitle("博客园");
            setSupportActionBar(mToolbar);
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            mActionBarDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolbar, R.string.drawer_open, R.string.drawer_close);
            mActionBarDrawerToggle.syncState();
            mDrawerLayout.setDrawerListener(mActionBarDrawerToggle);
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater().inflate(R.menu.menu_main, menu);
            return true;
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
    
            int id = item.getItemId();
    
            if (id == R.id.action_settings) {
                return true;
            }
    
            return super.onOptionsItemSelected(item);
        }
    }

    主滑动页面ViewPager适配器:

     1 package com.lcw.rabbit.myblog.adapter;
     2 
     3 import android.support.v4.app.Fragment;
     4 import android.support.v4.app.FragmentManager;
     5 import android.support.v4.app.FragmentPagerAdapter;
     6 
     7 import java.util.ArrayList;
     8 import java.util.List;
     9 
    10 /**
    11  * 主页面VierPager适配器
    12  * Created by Lichenwei
    13  * Date: 2015-08-16
    14  * Time: 13:47
    15  */
    16 public class ViewPagerAdapter extends FragmentPagerAdapter {
    17 
    18     private List<Fragment> mFragments;
    19     private List<String> mTitles;
    20 
    21     public ViewPagerAdapter(FragmentManager fm) {
    22         super(fm);
    23         mFragments = new ArrayList<Fragment>();
    24         mTitles = new ArrayList<String>();
    25     }
    26 
    27     /**
    28      * 新添Fragment内容和标题
    29      * @param fragment
    30      * @param title
    31      */
    32     public void addFragment(Fragment fragment, String title) {
    33         mFragments.add(fragment);
    34         mTitles.add(title);
    35     }
    36 
    37     @Override
    38     public Fragment getItem(int position) {
    39         return mFragments.get(position);
    40     }
    41 
    42     @Override
    43     public int getCount() {
    44         return mFragments.size();
    45     }
    46 
    47     @Override
    48     public CharSequence getPageTitle(int position) {
    49         return mTitles.get(position);
    50     }
    51 }

    至于ViewPager所承载的Fragment这里就不贴出来了,很简单的显示一个TextView。 

    今天先写到这里,改天继续更新,有什么建议或疑问,可以在文章评论给我留言。

    接下篇:《安卓开发笔记——打造属于自己的博客园APP(二)

    作者:李晨玮
    出处:http://www.cnblogs.com/lichenwei/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
    正在看本人博客的这位童鞋,我看你气度不凡,谈吐间隐隐有王者之气,日后必有一番作为!旁边有“推荐”二字,你就顺手把它点了吧,相得准,我分文不收;相不准,你也好回来找我!

  • 相关阅读:
    oracle当需要commit
    Win7 扩容磁盘分区
    MP3的频率、比特率、码率与音质的关系
    关于cocos2dx 3.0升级崩溃报错(unable to load native library) 和(Fatal signal 11 (SIGSEGV) at 0x00000000)
    开机黑屏 仅仅显示鼠标 电脑黑屏 仅仅有鼠标 移动 [已成功解决]
    Java串口通信具体解释
    android 计时器,倒计时
    联想A208T ROOT
    三层架构(我的理解及具体分析)
    Java实现BASE64编解码
  • 原文地址:https://www.cnblogs.com/lichenwei/p/4734702.html
Copyright © 2020-2023  润新知