Tag:仿9GAG设计过程 Material Desian 个人学习
Article From:https://www.cnblogs.com/lanxingren/p/9123158.html

There are words to say:

Ready to start learning a complete design process for Android applications. Ready to make a 9GAG like APP, front-end interface design + background data crawler + background interface design, and experience the whole process. Today we are going to finish the framework of the front end interface.

Results map:

Layout code:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:app="http://schemas.android.com/apk/res-auto"
 4     xmlns:tools="http://schemas.android.com/tools"
 5     android:id="@+id/drawer_layout"
 6     android:layout_width="match_parent"
 7     android:layout_height="match_parent"
 8     android:fitsSystemWindows="true"
 9     tools:openDrawer="start">
10 
11     <include
12         layout="@layout/activity_main_appbar"
13         android:layout_width="match_parent"
14         android:layout_height="match_parent" />
15 
16     <android.support.design.widget.NavigationView
17         android:id="@+id/nav_view"
18         android:layout_width="wrap_content"
19         android:layout_height="match_parent"
20         android:layout_gravity="start"
21         android:fitsSystemWindows="false"
22         app:headerLayout="@layout/activity_main_drawer_head"
23         app:menu="@menu/activity_main_drawer_menu"
24         android:theme="@style/MenuTextStyle"
25          />
26 
27 </android.support.v4.widget.DrawerLayout>

The main activity uses the layout of the DrawerLayout, by setting the openDrawer property of the DrawerLayout and the gravity property of the NavigationView to implement the tension area on the left side.

Let’s take a look at the layout of NavigationView’s head and the layout of menu:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <RelativeLayout
 3     xmlns:android="http://schemas.android.com/apk/res/android"
 4     android:layout_width="match_parent"
 5     android:layout_height="?attr/actionBarSize"
 6     android:background="@color/background">
 7 
 8     <RelativeLayout
 9         android:layout_width="match_parent"
10         android:layout_height="match_parent">
11         <de.hdodenhof.circleimageview.CircleImageView
12             android:id="@+id/circleImageView"
13             android:layout_width="28dp"
14             android:layout_height="28dp"
15             android:layout_centerVertical="true"
16             android:layout_marginLeft="14dp"/>
17 
18         <TextView
19             android:layout_width="wrap_content"
20             android:layout_height="wrap_content"
21             android:text="Lazier "
22             android:layout_centerVertical="true"
23             android:layout_marginLeft="14dp"
24             android:layout_toRightOf="@id/circleImageView"
25             android:textColor="@color/colorPrimary"/>
26         <ImageView
27             android:id="@+id/imageView"
28             android:layout_width="wrap_content"
29             android:layout_height="wrap_content"
30             android:src="@drawable/ic_settings_gray_24dp"
31             android:layout_centerVertical="true"
32             android:layout_marginRight="14dp"
33             android:layout_alignParentRight="true"/>
34     </RelativeLayout>
35 
36     <View
37         android:layout_alignParentBottom="true"
38         android:layout_width="match_parent"
39         android:layout_height="1dp"
40         android:background="?android:listDivider"
41         />
42 </RelativeLayout>

The CircleImageView component is used here to achieve the image scaling and cropping as a circular layout for the top left corner. And because there is no direct dividing line between the layout of the head and the layout of menu, a segmentation line is implemented by View.

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <menu xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:tools="http://schemas.android.com/tools"
 4     tools:showIn="navigation_view">
 5 
 6     <group
 7         android:id="@+id/group1"
 8         android:checkableBehavior="single">
 9         <item
10             android:id="@+id/nav_home"
11             android:icon="@drawable/ic_home_gray_24dp"
12             android:title="@string/home" />
13         <item
14             android:id="@+id/nav_notifications"
15             android:icon="@drawable/ic_notifications_gray_24dp"
16             android:title="@string/notifications" />
17     </group>
18 
19     <group android:id="@+id/group2">
20         <item
21             android:id="@+id/nav_share"
22             android:icon="@drawable/ic_share_gray_24dp"
23             android:title="@string/share" />
24         <item
25             android:id="@+id/nav_send"
26             android:icon="@drawable/ic_send_gray_24dp"
27             android:title="@string/send" />
28     </group>
29 
30 </menu>

The layout of the left menu is consistent with that of the main menu, and is implemented through the configuration file of menu.

There are two problems here:

  • The left menu font is not bold, but it needs to be bold
  • The spacing between the icon and text on the left menu layout is too large.

The first problem is to set a theme for NavigationView. The main meaning of the theme is the bold font.

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

The second problem, by reading the source code of NavigationView, gradually found the item layout file, the layout file is design_navigation_menu_item.xml, so the layout file is copied to layout, and DRawablePadding changed to 20dp, the following code:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <merge xmlns:android="http://schemas.android.com/apk/res/android">
 3 
 4     <CheckedTextView
 5         android:id="@+id/design_menu_item_text"
 6         android:layout_width="0dp"
 7         android:layout_height="match_parent"
 8         android:layout_weight="1"
 9         android:drawablePadding="20dp"
10         android:gravity="center_vertical|start"
11         android:maxLines="1"
12         android:textAppearance="@style/TextAppearance.AppCompat.Body2"/>
13 
14     <ViewStub
15         android:id="@+id/design_menu_item_action_area_stub"
16         android:inflatedId="@+id/design_menu_item_action_area"
17         android:layout="@layout/design_menu_item_action_area"
18         android:layout_width="wrap_content"
19         android:layout_height="match_parent"/>
20 
21 </merge>

Insert a point of knowledge:

You can directly generate the icons that need to be used directly through Android Studio. The icons are generated directly through Android Studio, and the steps are as follows:

Next, the implementation of the main page is achieved through TabLayout+ViewPage.

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:app="http://schemas.android.com/apk/res-auto"
 4     xmlns:tools="http://schemas.android.com/tools"
 5     android:layout_width="match_parent"
 6     android:layout_height="match_parent"
 7     tools:context=".activity.MainActivity">
 8 
 9     <android.support.design.widget.AppBarLayout
10         android:layout_width="match_parent"
11         android:layout_height="wrap_content"
12         android:theme="@style/AppTheme.AppBarOverlay">
13 
14         <android.support.v7.widget.Toolbar
15             android:id="@+id/toolbar"
16             android:layout_width="match_parent"
17             android:layout_height="?attr/actionBarSize"
18             android:background="?attr/colorPrimary"
19             app:layout_scrollFlags="scroll|enterAlways"
20             app:popupTheme="@style/AppTheme.PopupOverlay" />
21 
22         <android.support.design.widget.TabLayout
23             android:id="@+id/tabLayout"
24             android:layout_width="match_parent"
25             android:layout_height="wrap_content"
26             app:tabBackground="@color/background"
27             app:tabIndicatorColor="@color/colorPrimary"
28             app:tabTextColor="@color/defaultColor"
29             app:tabSelectedTextColor="@color/colorPrimary"
30             app:tabTextAppearance="@style/TabText"/>
31 
32     </android.support.design.widget.AppBarLayout>
33 
34     <android.support.v4.view.ViewPager
35         android:id="@+id/viewPage"
36         android:layout_width="match_parent"
37         android:layout_height="match_parent"
38         app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
39 
40 </android.support.design.widget.CoordinatorLayout>

 

Here are a few points to be paid attention to:

  • Toolbar disappears by setting scroll|enterAlways for the layout_scrollFlags property of Toolbar and setting the layout_behavior property to ViewPager to slide.That is, when the component of layout_behavior is set to slide, the component that sets layout_scrollFlags will move out of the screen.
  •  Set a font style for TabLayout’s tabTextAppearance to achieve Tab page BOLD effect.

The following is mainly about the code of part activity.

  1 package com.example.lanxingren.imitating9gag.activity;
  2 
  3 import android.os.Bundle;
  4 import android.support.design.widget.NavigationView;
  5 import android.support.design.widget.TabLayout;
  6 import android.support.v4.app.Fragment;
  7 import android.support.v4.view.GravityCompat;
  8 import android.support.v4.view.ViewPager;
  9 import android.support.v4.widget.DrawerLayout;
 10 import android.support.v7.app.ActionBarDrawerToggle;
 11 import android.support.v7.app.AppCompatActivity;
 12 import android.support.v7.widget.Toolbar;
 13 import android.view.Menu;
 14 import android.view.MenuItem;
 15 
 16 import com.example.lanxingren.imitating9gag.R;
 17 import com.example.lanxingren.imitating9gag.adapter.MyFragmentPagerAdapter;
 18 import com.example.lanxingren.imitating9gag.fragment.HomeFragment;
 19 import com.squareup.picasso.Picasso;
 20 
 21 import java.util.ArrayList;
 22 import java.util.List;
 23 
 24 import butterknife.BindView;
 25 import butterknife.ButterKnife;
 26 import de.hdodenhof.circleimageview.CircleImageView;
 27 
 28 public class MainActivity extends AppCompatActivity
 29         implements NavigationView.OnNavigationItemSelectedListener {
 30 
 31     @BindView(R.id.toolbar)
 32     Toolbar toolbar;
 33     @BindView(R.id.drawer_layout)
 34     DrawerLayout drawer;
 35     @BindView(R.id.nav_view)
 36     NavigationView navigationView;
 37     @BindView(R.id.tabLayout)
 38     TabLayout tabLayout;
 39     @BindView(R.id.viewPage)
 40     ViewPager viewPager;
 41 
 42     @Override
 43     protected void onCreate(Bundle savedInstanceState) {
 44         super.onCreate(savedInstanceState);
 45 
 46         setContentView(R.layout.activity_main);
 47 
 48         ButterKnife.bind(this);
 49 
 50         //Setting up ActionBar
 51         setSupportActionBar(toolbar);
 52 
 53         //Set up DrawerLayout monitoring events, the latter two of which are voice to disabled people.
 54         ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
 55                 this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
 56         //Set the three bar icon in the upper left corner
 57         toggle.syncState();
 58         drawer.addDrawerListener(toggle);
 59 
 60         //Setting up a drawer for a listener
 61         navigationView.setNavigationItemSelectedListener(this);
 62 
 63         //Direct findViewById will lead to NPE, the head of head part of drawer.
 64         CircleImageView circleImageView = navigationView.getHeaderView(0)
 65                 .findViewById(R.id.circleImageView);
 66         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")
 67                 .into(circleImageView);
 68 
 69         //The adapter that defines the viewPage
 70         List<Fragment> fragments = new ArrayList();
 71         fragments.add(new HomeFragment());
 72         fragments.add(new HomeFragment());
 73         MyFragmentPagerAdapter adapter = new MyFragmentPagerAdapter(getSupportFragmentManager(), fragments);
 74 
 75         viewPager.setAdapter(adapter);
 76         tabLayout.setupWithViewPager(viewPager);
 77     }
 78 
 79     @Override
 80     public void onBackPressed() {
 81         if (drawer.isDrawerOpen(GravityCompat.START)) {
 82             drawer.closeDrawer(GravityCompat.START);
 83         } else {
 84             super.onBackPressed();
 85         }
 86     }
 87 
 88     /**
 89      * Top right button icon 90      * @param menu
 91      * @return
 92      */
 93     @Override
 94     public boolean onCreateOptionsMenu(Menu menu) {
 95         getMenuInflater().inflate(R.menu.main, menu);
 96         return true;
 97     }
 98 
 99     //Top right button click event
100     @Override
101     public boolean onOptionsItemSelected(MenuItem item) {
102         return super.onOptionsItemSelected(item);
103     }
104 
105     //Left drawer menu click event
106     @SuppressWarnings("StatementWithEmptyBody")
107     @Override
108     public boolean onNavigationItemSelected(MenuItem item) {
109         int id = item.getItemId();
110 
111         if (id == R.id.nav_home) {
112 
113         } else if (id == R.id.nav_notifications) {
114 
115         } else if (id == R.id.nav_send) {
116 
117         } else if (id == R.id.nav_share) {
118 
119         }
120 
121         drawer.closeDrawer(GravityCompat.START);
122         return true;
123     }
124 
125 }

Knowledge points:

  • Use ButterKnife instead of findViewById to get components.
  • Using Picasso to load network images, head and interior are loaded through this way.
  • The MyFragmentPagerAdapter adapter is defined to implement the layout of ViewPage.

MyFragmentPagerAdapterThe internal data is actually HomeFragment, and the layout of the Fragment is actually a simple RecyclerView. The following HomeFragment Code:

 1 package com.example.lanxingren.imitating9gag.fragment;
 2 
 3 import android.os.Bundle;
 4 import android.support.v4.app.Fragment;
 5 import android.support.v7.widget.LinearLayoutManager;
 6 import android.support.v7.widget.RecyclerView;
 7 import android.view.LayoutInflater;
 8 import android.view.View;
 9 import android.view.ViewGroup;
10 
11 import com.example.lanxingren.imitating9gag.R;
12 import com.example.lanxingren.imitating9gag.adapter.NewsAdapter;
13 import com.example.lanxingren.imitating9gag.bean.NewsBean;
14 
15 import java.util.ArrayList;
16 import java.util.List;
17 
18 /**
19  */
20 public class HomeFragment extends Fragment {
21 
22     @Override
23     public void onCreate(Bundle savedInstanceState) {
24         super.onCreate(savedInstanceState);
25     }
26 
27     @Override
28     public View onCreateView(LayoutInflater inflater, ViewGroup container,
29                              Bundle savedInstanceState) {
30         return inflater.inflate(R.layout.fragment_home, container, false);
31     }
32 
33     @Override
34     public void onStart() {
35         super.onStart();
36         List<NewsBean> newsBeans = new ArrayList<NewsBean>();
37 
38         for (int i = 0; i < 30; i++) {
39             newsBeans.add(new NewsBean("This is an interesting passage of "+ Integer.toString (i+1) +". ",
40                     "http://ws4.sinaimg.cn/mw600/6c560b83ly1fruncq3z03j20ks0rs41b.jpg", 0));
41         }
42 
43         LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
44 
45         RecyclerView recyclerView = getView().findViewById(R.id.recyclerView);
46         recyclerView.setAdapter(new NewsAdapter(newsBeans));
47         recyclerView.setLayoutManager(linearLayoutManager);
48     }
49 }

 

RecyrViewWith the NewsAdapter adapter, the adapter code is as follows:

 1 package com.example.lanxingren.imitating9gag.adapter;
 2 
 3 import android.content.Context;
 4 import android.support.annotation.NonNull;
 5 import android.support.v7.widget.CardView;
 6 import android.support.v7.widget.RecyclerView;
 7 import android.view.LayoutInflater;
 8 import android.view.View;
 9 import android.view.ViewGroup;
10 import android.widget.ImageView;
11 import android.widget.TextView;
12 
13 import com.example.lanxingren.imitating9gag.R;
14 import com.example.lanxingren.imitating9gag.bean.NewsBean;
15 import com.squareup.picasso.Picasso;
16 
17 import java.util.List;
18 
19 public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.NewsHolder> {
20 
21     private List<NewsBean> myNewsList;
22     private Context myContext;
23 
24     static class NewsHolder extends RecyclerView.ViewHolder {
25         CardView cardView;
26         TextView textView;
27         ImageView imageView;
28 
29         private NewsHolder (View view) {
30             super(view);
31             cardView = (CardView) view;
32             textView = view.findViewById(R.id.item_text);
33             imageView = view.findViewById(R.id.item_image);
34         }
35     }
36 
37     public NewsAdapter (List<NewsBean> newsList) {
38         this.myNewsList = newsList;
39     }
40 
41     @Override
42     public int getItemCount() {
43         int count = 0;
44         if (myNewsList != null) {
45             count = myNewsList.size();
46         }
47         return count;
48     }
49 
50     @NonNull
51     @Override
52     public NewsHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
53         if (myContext == null) {
54             myContext = parent.getContext();
55         }
56         View view = LayoutInflater.from(myContext).inflate(R.layout.item_news, parent, false);
57         return new NewsHolder(view);
58     }
59 
60     @Override
61     public void onBindViewHolder(@NonNull NewsHolder holder, int position) {
62         NewsBean newsBean = myNewsList.get(position);
63         holder.textView.setText(newsBean.getTitle());
64 
65         int screenWidth = myContext.getResources()
66                 .getDisplayMetrics()
67                 .widthPixels;
68         Picasso.with(myContext)
69                 .load(newsBean.getPicUrl())
70                 .resize(screenWidth, 0)
71                 .into(holder.imageView);
72     }
73 }

 

The layout of each item is item_news, and the specific layout will be looked at later. In onBindViewHolder, the textView of the layout is set up, and the picture is set for imageView.

Before looking at other people’s blogs, I often define a myContext in the adapter. I always think it’s useless. But in the actual process of compiling the adapter, it is found that myContext still has many uses.

Let’s take a look at the layout of item_news. The code is as follows:

  1 <?xml version="1.0" encoding="utf-8"?>
  2 <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
  3     android:layout_width="match_parent"
  4     android:layout_height="wrap_content"
  5     xmlns:app="http://schemas.android.com/apk/res-auto"
  6     android:layout_marginVertical="10dp"
  7     app:cardCornerRadius="0dp"
  8     android:elevation="0dp">
  9     <LinearLayout
 10         android:layout_width="match_parent"
 11         android:layout_height="wrap_content"
 12         android:orientation="vertical"
 13         >
 14         <RelativeLayout
 15             android:layout_width="match_parent"
 16             android:layout_height="40dp"
 17             android:gravity="center">
 18             <TextView
 19                 android:id="@+id/item_text"
 20                 android:textStyle="bold"
 21                 android:textColor="@color/colorPrimary"
 22                 android:layout_width="wrap_content"
 23                 android:layout_height="wrap_content"
 24                 android:layout_alignParentLeft="true"
 25                 android:layout_marginLeft="14dp"/>
 26             <ImageView
 27                 android:layout_width="wrap_content"
 28                 android:layout_height="wrap_content"
 29                 android:layout_alignParentRight="true"
 30                 android:src="@drawable/ic_expand_more_gray_24dp"
 31                 android:layout_marginRight="14dp"/>
 32         </RelativeLayout>
 33         <ImageView
 34             android:id="@+id/item_image"
 35             android:layout_width="match_parent"
 36             android:layout_height="wrap_content"
 37             android:scaleType="fitCenter"/>
 38         <LinearLayout
 39             android:layout_width="match_parent"
 40             android:layout_height="40dp"
 41             android:orientation="horizontal"
 42             android:gravity="center">
 43             <LinearLayout
 44                 android:layout_width="0dp"
 45                 android:layout_weight="1"
 46                 android:layout_height="wrap_content"
 47                 android:orientation="horizontal">
 48                 <ImageView
 49                     android:layout_width="0dp"
 50                     android:layout_weight="1"
 51                     android:layout_height="wrap_content"
 52                     android:src="@drawable/ic_thumb_up_gray_24dp"
 53                     android:scaleType="fitEnd"/>
 54                 <TextView
 55                     android:layout_width="0dp"
 56                     android:layout_weight="1"
 57                     android:layout_height="wrap_content"
 58                     android:gravity="center"
 59                     android:text="5k"/>
 60                 <ImageView
 61                     android:layout_width="0dp"
 62                     android:layout_weight="1"
 63                     android:layout_height="wrap_content"
 64                     android:src="@drawable/ic_thumb_down_gray_24dp"
 65                     android:scaleType="fitStart"/>
 66             </LinearLayout>
 67 
 68             <View
 69                 android:layout_width="1dp"
 70                 android:layout_height="20dp"
 71                 android:background="?android:listDivider"/>
 72 
 73             <LinearLayout
 74                 android:layout_width="0dp"
 75                 android:layout_weight="1"
 76                 android:layout_height="wrap_content"
 77                 android:gravity="center">
 78                 <ImageView
 79                     android:layout_width="0dp"
 80                     android:layout_weight="1"
 81                     android:layout_height="wrap_content"
 82                     android:src="@drawable/ic_comment_gray_24dp"
 83                     android:scaleType="fitEnd"
 84                     android:paddingRight="5dp"/>
 85                 <TextView
 86                     android:layout_width="0dp"
 87                     android:layout_weight="1"
 88                     android:layout_height="wrap_content"
 89                     android:gravity="left"
 90                     android:text="46"
 91                     android:paddingLeft="5dp"/>
 92             </LinearLayout>
 93 
 94             <View
 95                 android:layout_width="1dp"
 96                 android:layout_height="20dp"
 97                 android:background="?android:listDivider"/>
 98 
 99             <LinearLayout
100                 android:layout_width="0dp"
101                 android:layout_weight="1"
102                 android:layout_height="wrap_content"
103                 android:gravity="center">
104                 <ImageView
105                     android:layout_width="0dp"
106                     android:layout_weight="1"
107                     android:layout_height="wrap_content"
108                     android:src="@drawable/ic_share_gray_24dp"
109                     android:scaleType="fitEnd"
110                     android:paddingRight="5dp"/>
111                 <TextView
112                     android:layout_width="0dp"
113                     android:layout_weight="1"
114                     android:layout_height="wrap_content"
115                     android:gravity="left"
116                     android:text="Share "
117                     android:paddingLeft="5dp"/>
118             </LinearLayout>
119         </LinearLayout>
120     </LinearLayout>
121 
122 </android.support.v7.widget.CardView>

Each item uses a card layout, using official CardView components.

By setting cardCornerRadius, the rounded arc is set to 0, so that the card is a positive rectangle.

ImageViewThe meaning of scaleType is how to fill a picture, where fitCenter is centered, fitStart is left aligned, and fitEnd is right justified.

 

Write hastily, if there is any doubt or wrong place, welcome the message to correct.

Link of this Article: The process of imitating 9GAG (1)

Leave a Reply

Your email address will not be published. Required fields are marked *