仿9GAG制作过程(一)

  • 有话要说
  • 成果图
  • 布局代码
  • 插一个知识点

有话要说

准备开始学习Android应用程序的一个完整的设计过程。准备做一个仿9GAG的APP,前端界面设计+后台数据爬虫+后台接口设计,整个流程体验一遍。今天准备先把前端界面的框架给完成了。

成果图

布局代码

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout 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/drawer_layout"android:layout_width="match_parent"android:layout_height="match_parent"android:fitsSystemWindows="true"tools:openDrawer="start"><includelayout="@layout/activity_main_appbar"android:layout_width="match_parent"android:layout_height="match_parent" /><android.support.design.widget.NavigationViewandroid:id="@+id/nav_view"android:layout_width="wrap_content"android:layout_height="match_parent"android:layout_gravity="start"android:fitsSystemWindows="false"app:headerLayout="@layout/activity_main_drawer_head"app:menu="@menu/activity_main_drawer_menu"android:theme="@style/MenuTextStyle"/></android.support.v4.widget.DrawerLayout>

主活动用了DrawerLayout的布局方式,通过设置DrawerLayoutopenDrawer属性以及NavigationViewgravity属性来实现左侧的测拉区域。

下面来看看NavigationView的头部布局以及menu的布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="?attr/actionBarSize"android:background="@color/background"><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"><de.hdodenhof.circleimageview.CircleImageViewandroid:id="@+id/circleImageView"android:layout_width="28dp"android:layout_height="28dp"android:layout_centerVertical="true"android:layout_marginLeft="14dp"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="懒星人"android:layout_centerVertical="true"android:layout_marginLeft="14dp"android:layout_toRightOf="@id/circleImageView"android:textColor="@color/colorPrimary"/><ImageViewandroid:id="@+id/imageView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/ic_settings_gray_24dp"android:layout_centerVertical="true"android:layout_marginRight="14dp"android:layout_alignParentRight="true"/></RelativeLayout><Viewandroid:layout_alignParentBottom="true"android:layout_width="match_parent"android:layout_height="1dp"android:background="?android:listDivider"/>
</RelativeLayout>

这里用到了CircleImageView组件来实现图片缩放裁剪成圆形,作为左上角头像的布局。并且由于头部的布局与menu的布局之间没有直接的分割线,就用View来实现了一个分割线。

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"tools:showIn="navigation_view"><groupandroid:id="@+id/group1"android:checkableBehavior="single"><itemandroid:id="@+id/nav_home"android:icon="@drawable/ic_home_gray_24dp"android:title="@string/home" /><itemandroid:id="@+id/nav_notifications"android:icon="@drawable/ic_notifications_gray_24dp"android:title="@string/notifications" /></group><group android:id="@+id/group2"><itemandroid:id="@+id/nav_share"android:icon="@drawable/ic_share_gray_24dp"android:title="@string/share" /><itemandroid:id="@+id/nav_send"android:icon="@drawable/ic_send_gray_24dp"android:title="@string/send" /></group></menu>

左侧menu的布局和主menu实现方式一致,通过menu的配置文件来实现。

在这里遇到了两个问题:

  • 左侧menu字体不是粗体,但是需要粗体
  • 左侧menu布局的图标和文字之间的间隔太大

第一个问题通过给NavigationView设置了主题,主题的主要意义就是加粗字体,如下代码:

<style name="MenuTextStyle"><item name="android:textStyle">bold</item>
</style>

第二个问题,通过阅读NavigationView的源码逐步找到了item的布局文件,布局文件为design_navigation_menu_item.xml,于是将布局文件复制到layout下,并将drawablePadding改成了20dp,如下代码:

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"><CheckedTextViewandroid:id="@+id/design_menu_item_text"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:drawablePadding="20dp"android:gravity="center_vertical|start"android:maxLines="1"android:textAppearance="@style/TextAppearance.AppCompat.Body2"/><ViewStubandroid:id="@+id/design_menu_item_action_area_stub"android:inflatedId="@+id/design_menu_item_action_area"android:layout="@layout/design_menu_item_action_area"android:layout_width="wrap_content"android:layout_height="match_parent"/></merge>

插一个知识点

可以直接通过Android Studio来生成需要用到的图标,这里的图标我都是直接通过Android Studio生成的,生成步骤如下:

接下来说一下主页面的实现,是通过TabLayout+ViewPage的方式来实现的,先来看代码:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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"tools:context=".activity.MainActivity"><android.support.design.widget.AppBarLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:theme="@style/AppTheme.AppBarOverlay"><android.support.v7.widget.Toolbarandroid:id="@+id/toolbar"android:layout_width="match_parent"android:layout_height="?attr/actionBarSize"android:background="?attr/colorPrimary"app:layout_scrollFlags="scroll|enterAlways"app:popupTheme="@style/AppTheme.PopupOverlay" /><android.support.design.widget.TabLayoutandroid:id="@+id/tabLayout"android:layout_width="match_parent"android:layout_height="wrap_content"app:tabBackground="@color/background"app:tabIndicatorColor="@color/colorPrimary"app:tabTextColor="@color/defaultColor"app:tabSelectedTextColor="@color/colorPrimary"app:tabTextAppearance="@style/TabText"/></android.support.design.widget.AppBarLayout><android.support.v4.view.ViewPagerandroid:id="@+id/viewPage"android:layout_width="match_parent"android:layout_height="match_parent"app:layout_behavior="@string/appbar_scrolling_view_behavior"/></android.support.design.widget.CoordinatorLayout>

这里需要注意一下几个知识点:

  • 通过给Toolbarlayout_scrollFlags属性设置scroll|enterAlways并且给ViewPager设置layout_behavior属性来实现滑动的时候Toolbar消失。即当设置layout_behavior的组件滑动时设置layout_scrollFlags的组件会移出屏幕
  • TabLayouttabTextAppearance设置一个字体样式来实现Tab页加粗效果

下面主要来说一下activity部分的代码,先上代码:

package com.example.lanxingren.imitating9gag.activity;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.GravityCompat;
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.example.lanxingren.imitating9gag.R;
import com.example.lanxingren.imitating9gag.adapter.MyFragmentPagerAdapter;
import com.example.lanxingren.imitating9gag.fragment.HomeFragment;
import com.squareup.picasso.Picasso;import java.util.ArrayList;
import java.util.List;import butterknife.BindView;
import butterknife.ButterKnife;
import de.hdodenhof.circleimageview.CircleImageView;public class MainActivity extends AppCompatActivityimplements NavigationView.OnNavigationItemSelectedListener {@BindView(R.id.toolbar)Toolbar toolbar;@BindView(R.id.drawer_layout)DrawerLayout drawer;@BindView(R.id.nav_view)NavigationView navigationView;@BindView(R.id.tabLayout)TabLayout tabLayout;@BindView(R.id.viewPage)ViewPager viewPager;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ButterKnife.bind(this);//设置ActionBarsetSupportActionBar(toolbar);//设置DrawerLayout的监听事件,其中后两个参数是给残障人士的语音ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);//设置左上角的三杠图标toggle.syncState();drawer.addDrawerListener(toggle);//设置抽屉的监听事件navigationView.setNavigationItemSelectedListener(this);//直接findViewById会导致NPE,抽屉head部分的头像CircleImageView circleImageView = navigationView.getHeaderView(0).findViewById(R.id.circleImageView);Picasso.with(this).load("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1527745766743&di=c24134fe5233902ca1a60a8665c30a35&imgtype=0&src=http%3A%2F%2Fimg1.sc115.com%2Fuploads%2Fsc%2Fjpg%2F144%2F18628.jpg").into(circleImageView);//定义viewPage的适配器List<Fragment> fragments = new ArrayList();fragments.add(new HomeFragment());fragments.add(new HomeFragment());MyFragmentPagerAdapter adapter = new MyFragmentPagerAdapter(getSupportFragmentManager(), fragments);viewPager.setAdapter(adapter);tabLayout.setupWithViewPager(viewPager);}@Overridepublic void onBackPressed() {if (drawer.isDrawerOpen(GravityCompat.START)) {drawer.closeDrawer(GravityCompat.START);} else {super.onBackPressed();}}/*** 右上角按钮图标* @param menu* @return*/@Overridepublic boolean onCreateOptionsMenu(Menu menu) {getMenuInflater().inflate(R.menu.main, menu);return true;}//右上角按钮点击事件@Overridepublic boolean onOptionsItemSelected(MenuItem item) {return super.onOptionsItemSelected(item);}//左侧抽屉menu点击事件@SuppressWarnings("StatementWithEmptyBody")@Overridepublic boolean onNavigationItemSelected(MenuItem item) {int id = item.getItemId();if (id == R.id.nav_home) {} else if (id == R.id.nav_notifications) {} else if (id == R.id.nav_send) {} else if (id == R.id.nav_share) {}drawer.closeDrawer(GravityCompat.START);return true;}}

知识点:

  • 用了ButterKnife而不是findViewById来获取组件
  • 用了Picasso来加载网络图片,头像以及内部都是通过这种方式来加载的
  • 定义了MyFragmentPagerAdapter适配器来实现ViewPage的布局

MyFragmentPagerAdapter内部的数据实际上为HomeFragment,而该Fragment的布局实际上只是一个简单的RecyclerView,下面上HomeFragment的代码:

package com.example.lanxingren.imitating9gag.fragment;import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;import com.example.lanxingren.imitating9gag.R;
import com.example.lanxingren.imitating9gag.adapter.NewsAdapter;
import com.example.lanxingren.imitating9gag.bean.NewsBean;import java.util.ArrayList;
import java.util.List;/***/
public class HomeFragment extends Fragment {@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {return inflater.inflate(R.layout.fragment_home, container, false);}@Overridepublic void onStart() {super.onStart();List<NewsBean> newsBeans = new ArrayList<NewsBean>();for (int i = 0; i < 30; i++) {newsBeans.add(new NewsBean("这是第 " + Integer.toString(i+1) + " 条有趣的段子!","http://ws4.sinaimg.cn/mw600/6c560b83ly1fruncq3z03j20ks0rs41b.jpg", 0));}LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());RecyclerView recyclerView = getView().findViewById(R.id.recyclerView);recyclerView.setAdapter(new NewsAdapter(newsBeans));recyclerView.setLayoutManager(linearLayoutManager);}
}

RecyrView用了NewsAdapter适配器,适配器代码如下:

package com.example.lanxingren.imitating9gag.adapter;import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;import com.example.lanxingren.imitating9gag.R;
import com.example.lanxingren.imitating9gag.bean.NewsBean;
import com.squareup.picasso.Picasso;import java.util.List;public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.NewsHolder> {private List<NewsBean> myNewsList;private Context myContext;static class NewsHolder extends RecyclerView.ViewHolder {CardView cardView;TextView textView;ImageView imageView;private NewsHolder (View view) {super(view);cardView = (CardView) view;textView = view.findViewById(R.id.item_text);imageView = view.findViewById(R.id.item_image);}}public NewsAdapter (List<NewsBean> newsList) {this.myNewsList = newsList;}@Overridepublic int getItemCount() {int count = 0;if (myNewsList != null) {count = myNewsList.size();}return count;}@NonNull@Overridepublic NewsHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {if (myContext == null) {myContext = parent.getContext();}View view = LayoutInflater.from(myContext).inflate(R.layout.item_news, parent, false);return new NewsHolder(view);}@Overridepublic void onBindViewHolder(@NonNull NewsHolder holder, int position) {NewsBean newsBean = myNewsList.get(position);holder.textView.setText(newsBean.getTitle());int screenWidth = myContext.getResources().getDisplayMetrics().widthPixels;Picasso.with(myContext).load(newsBean.getPicUrl()).resize(screenWidth, 0).into(holder.imageView);}
}

每一项的布局为item_news,一会儿看具体布局。在onBindViewHolder中给布局的textView设置了文字,给imageView设置了图片。

之前看别人的博客,经常会在适配器中定义一个myContext,我一直觉得没什么用。但是在这次实际编写适配器的过程中,发现了myContext还是有很多地方要用到的。

下面来看看item_news的布局,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_marginVertical="10dp"app:cardCornerRadius="0dp"android:elevation="0dp"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="40dp"android:gravity="center"><TextViewandroid:id="@+id/item_text"android:textStyle="bold"android:textColor="@color/colorPrimary"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentLeft="true"android:layout_marginLeft="14dp"/><ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:src="@drawable/ic_expand_more_gray_24dp"android:layout_marginRight="14dp"/></RelativeLayout><ImageViewandroid:id="@+id/item_image"android:layout_width="match_parent"android:layout_height="wrap_content"android:scaleType="fitCenter"/><LinearLayoutandroid:layout_width="match_parent"android:layout_height="40dp"android:orientation="horizontal"android:gravity="center"><LinearLayoutandroid:layout_width="0dp"android:layout_weight="1"android:layout_height="wrap_content"android:orientation="horizontal"><ImageViewandroid:layout_width="0dp"android:layout_weight="1"android:layout_height="wrap_content"android:src="@drawable/ic_thumb_up_gray_24dp"android:scaleType="fitEnd"/><TextViewandroid:layout_width="0dp"android:layout_weight="1"android:layout_height="wrap_content"android:gravity="center"android:text="5k"/><ImageViewandroid:layout_width="0dp"android:layout_weight="1"android:layout_height="wrap_content"android:src="@drawable/ic_thumb_down_gray_24dp"android:scaleType="fitStart"/></LinearLayout><Viewandroid:layout_width="1dp"android:layout_height="20dp"android:background="?android:listDivider"/><LinearLayoutandroid:layout_width="0dp"android:layout_weight="1"android:layout_height="wrap_content"android:gravity="center"><ImageViewandroid:layout_width="0dp"android:layout_weight="1"android:layout_height="wrap_content"android:src="@drawable/ic_comment_gray_24dp"android:scaleType="fitEnd"android:paddingRight="5dp"/><TextViewandroid:layout_width="0dp"android:layout_weight="1"android:layout_height="wrap_content"android:gravity="left"android:text="46"android:paddingLeft="5dp"/></LinearLayout><Viewandroid:layout_width="1dp"android:layout_height="20dp"android:background="?android:listDivider"/><LinearLayoutandroid:layout_width="0dp"android:layout_weight="1"android:layout_height="wrap_content"android:gravity="center"><ImageViewandroid:layout_width="0dp"android:layout_weight="1"android:layout_height="wrap_content"android:src="@drawable/ic_share_gray_24dp"android:scaleType="fitEnd"android:paddingRight="5dp"/><TextViewandroid:layout_width="0dp"android:layout_weight="1"android:layout_height="wrap_content"android:gravity="left"android:text="分享"android:paddingLeft="5dp"/></LinearLayout></LinearLayout></LinearLayout></android.support.v7.widget.CardView>

每一项使用的是卡片式布局,使用了官方的CardView组件。

通过设置cardCornerRadius来设置圆角弧度为0,使得卡片为正矩形。

ImageViewscaleType的意思是图片如何填充,其中fitCenter为居中填充,fitStart为左对齐填充,fitEnd为右对齐填充。

写的比较仓促,如有疑问或者错误的地方欢迎留言指正。

仿9GAG制作过程(一)相关推荐

  1. ss570122的雕刻机制作过程

    ss570122的雕刻机制作过程1 作者注:我将以前发表过的几个有关机械和驱动电路的DIY帖子重新整理组合一下重新发表(并会适当增加电源和主轴的DIY内容),为的是方便初入雕刻机制作的网友能够方便的了 ...

  2. 电脑绣花制版-仿版的过程与注意事项

    电脑绣花制版-仿版的过程与注意事项 所谓电脑绣花实样制版,指的是客户提供已经绣作好.形成绣花成品的花样.制版人员根据实样进行二次制版的过程,这也可称之为仿作.它与彩稿制版有以下几个比较: (一)实样制 ...

  3. (转载)连连看游戏外挂详细制作过程

    标 题: [原创]新人入手第一个游戏外挂,附上详细制作过程 作 者: caigui 时 间: 2013-01-09,00:56:16 链 接: http://bbs.pediy.com/showthr ...

  4. Js黑客帝国效果 文字下落 制作过程和思路

    效果预览: http://jsfiddle.net/dtdxrk/m8R6b/embedded/result/ Js黑客帝国效果 文字向下落制作过程和思路 1.css控制文字竖显示 2.动态添加div ...

  5. Ireport制作过程

    Ireport制作过程 1.首先要到Option下设置一下ClassPath添加文件夹 2.到预览->报表字段设置一下将要用到的字段 3.到编辑->查询报表->写sql语句,然后把语 ...

  6. 简易数字时钟软件详细制作过程

    这是我自己用VS2010制作的简易数字时钟小软件,在制作过程中收获知识不少,希望和初学MFC编程的朋友分享一下. 一.其功能有一下三点: 1.打开软件后,其程序自动获取当前电脑系统的日期.时间和周次, ...

  7. 通过WiFi控制智能小车机器人制作过程详解

    之前发的作品都是基于蓝牙控制的智能小车机器人,由于蓝牙的传输范围比较小,所以控制距离的局限性比较大,并且通过蓝牙传输视频会明显出现卡屏的现象. 而通过WiFi方式控制智能小车机器人能达到100米左右的 ...

  8. rpt水晶报表制作过程

    原文:rpt水晶报表制作过程 最近公司安排一个以前的项目,里面需要用到水晶报表,由于原来做这个项目的同事离职,所在公司的同事报表做成了rdlc类型的,而这类报表在加载的时候很难动态的从数据库加载数据, ...

  9. 电路制版工作笔记001---印刷电路板的制作过程

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 下面这个是比较严格的过程,四层板的制作流程: PCB 印刷电路板的制作过程 我们来看一下印刷电路板 ...

  10. 手工制作机器人用彩泥_印度神奇芒果干制作过程,看一遍顶三遍,游客:不会再吃了...

    印度神奇芒果干制作过程,看一遍顶三遍,游客:不会再吃了 随着我国经济迅速发展,人们生活水平得到了很大提升,物质消费得到满足以后,人们更注重精神需求,希望通过旅游要开放视野,放松心情,让自己体验不同地域 ...

最新文章

  1. 自兴人工智能——Python运算符和操作对象
  2. linux服务器多网卡bond
  3. UITableView刷新单个cell或者单个Section
  4. OpenGL Static Texture静态纹理的实例
  5. 【Linux C 多线程编程】互斥锁与条件变量
  6. 无法全新安装_好墙板更需好安装:护墙板安装新方法
  7. .NET 开源项目 Anet 介绍
  8. Java集合Stream类
  9. 关于RDLC使用导出PDF文件时,中文乱码解决方案
  10. 在pycharm中安装pygame
  11. Java 编程(基础面试题)
  12. 与计算机相关活动主题,计算机文化节活动策划书
  13. Win10锁屏之后屏幕自动关闭怎么办
  14. Doris export任务概率性cancelled第二种情况
  15. Winsock 10106错误解决方法
  16. MySQL45讲 读书笔记 22讲MySQL有哪些“饮鸩止渴”提高性能的方法
  17. 2019,关于我的故事
  18. 程序员工作9年月薪从1.5K到24K,网友:不如刚毕业985
  19. java中.的意思_java中“:”的意思是什么?
  20. JavaBeans 教程

热门文章

  1. 使用Java实现多个文件压缩打包
  2. Android浏览器翻译功能调研
  3. 计算机辅助翻译在翻译实践中的应用,计算机辅助翻译在翻译实践中的应用
  4. 英语语法 第一章 句子的形成——概说
  5. GoldWave教程分享:删除声道该怎么操作?
  6. SQL Server 数据库之视图(二)
  7. html css屏蔽右键,css右键菜单.html
  8. w10计算机右键管理,Win10右键菜单怎么管理
  9. 计算机图表制作教程,echarts入门教程 5分钟上手制作ECharts图表
  10. ime输入法android,创建输入法  |  Android 开发者  |  Android Developers