Android ActionBar application practice, high imitation WeChat Main Interface Design

Source: Internet
Author: User

 

After studying the previous two articles, I think you have a deep understanding of ActionBar. The only thing we lack is that we have only learned theoretical knowledge before. Although the knowledge has been mastered, it is hard to say whether or not the chain will fall into the project practice. So don't worry. In this article, I will lead everyone into the practical application of ActionBar and combine theory and practice perfectly.

If you have not read the first two articles, read them first.Complete parsing of Android ActionBar, using the best navigation bar officially recommended (on)AndComplete parsing of Android ActionBar, using the best navigation bar officially recommended (below).

I believe everyone will think that it is the most popular app on mobile phones, and almost everyone has installed it on their mobile phones. In addition to powerful functions, the interface is also very beautiful. Its ActionBar makes people look pleasing to the eye, as shown in:

As a technical benchmark in mobile apps, we should naturally learn more. The theme of today's practice is to imitate the implementation of the main interface.

Create an Android project named WeChatSample. To implement ActionBar, edit the main. xml file in the menu directory. The Code is as follows:

                The meaning of each attribute in this file has been explained in the previous two articles. Note that,  The icon specified in the tag is prepared in advance, and the specified title text is defined in string. in xml, I will attach the source code. You can find these icons and text in the source code. 

 

Observe the preceding main. xml and you will find a custom Action Provider called PlusActionProvider. This is mainly used to simulate the sub-menu of the plus sign. Below we will implement this class:

public class PlusActionProvider extends ActionProvider {private Context context;public PlusActionProvider(Context context) {super(context);this.context = context;}@Overridepublic View onCreateActionView() {return null;}@Overridepublic void onPrepareSubMenu(SubMenu subMenu) {subMenu.clear();subMenu.add(context.getString(R.string.plus_group_chat)).setIcon(R.drawable.ofm_group_chat_icon).setOnMenuItemClickListener(new OnMenuItemClickListener() {@Overridepublic boolean onMenuItemClick(MenuItem item) {return true;}});subMenu.add(context.getString(R.string.plus_add_friend)).setIcon(R.drawable.ofm_add_icon).setOnMenuItemClickListener(new OnMenuItemClickListener() {@Overridepublic boolean onMenuItemClick(MenuItem item) {return false;}});subMenu.add(context.getString(R.string.plus_video_chat)).setIcon(R.drawable.ofm_video_icon).setOnMenuItemClickListener(new OnMenuItemClickListener() {@Overridepublic boolean onMenuItemClick(MenuItem item) {return false;}});subMenu.add(context.getString(R.string.plus_scan)).setIcon(R.drawable.ofm_qrcode_icon).setOnMenuItemClickListener(new OnMenuItemClickListener() {@Overridepublic boolean onMenuItemClick(MenuItem item) {return false;}});subMenu.add(context.getString(R.string.plus_take_photo)).setIcon(R.drawable.ofm_camera_icon).setOnMenuItemClickListener(new OnMenuItemClickListener() {@Overridepublic boolean onMenuItemClick(MenuItem item) {return false;}});}@Overridepublic boolean hasSubMenu() {return true;}}
I have already introduced the Custom Action Provider method in the previous article. I believe it is very easy to understand when you look at this class. Here, we define five sub-menus in PlusActionProvider. Each sub-menu has a title and an icon, which correspond to the five sub-menus respectively. In addition, although a click event is defined for each sub-menu, the implementation in the click event is empty, because this article is just a simulated interface implementation, function.

 

Modify the code in MainActivity as follows:

public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);setOverflowShowingAlways();}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {getMenuInflater().inflate(R.menu.main, menu);return true;}@Overridepublic boolean onMenuOpened(int featureId, Menu menu) {if (featureId == Window.FEATURE_ACTION_BAR && menu != null) {if (menu.getClass().getSimpleName().equals(MenuBuilder)) {try {Method m = menu.getClass().getDeclaredMethod(setOptionalIconsVisible, Boolean.TYPE);m.setAccessible(true);m.invoke(menu, true);} catch (Exception e) {}}}return super.onMenuOpened(featureId, menu);}private void setOverflowShowingAlways() {try {ViewConfiguration config = ViewConfiguration.get(this);Field menuKeyField = ViewConfiguration.class.getDeclaredField(sHasPermanentMenuKey);menuKeyField.setAccessible(true);menuKeyField.setBoolean(config, false);} catch (Exception e) {e.printStackTrace();}}}
The code is not long and you are familiar with it. The onCreateOptionsMenu () method loads main. the onMenuOpened () method is used to display the icon of the Action button hidden in overflow, while the setOverflowShowingAlways () method shields the physical Menu key, otherwise, the overflow button cannot be displayed on the mobile phone with the physical Menu key.

 

Now we have implemented the ActionBar interface, but if you run it now, you will find that the effect and performance are far behind, we haven't made any minor adjustments to the font color and size, so we need to customize the ActionBar. Modify the styles. xml file with the following code:

  
   
   
   
   
   
  
Here, I adjusted the background color of ActionBar, the title text color and size, and the sub-menu background color to make it exactly the same as the overall style, the images used are also saved in the drawable folder. I have introduced the methods for customizing ActionBar styles in the previous article. If you are not familiar with the methods, you can refer to them again.

 

Finally, you need to make some modifications to AndroidManifest. xml, as shown below:

    ......    

Adds a logo attribute to the tag and an icon attribute to the tag. Run the program, as shown in the following figure:

As you can see, our interface is already very similar, and it is almost possible to be confused! Haha, I'm proud of it. However, if ActionBar can be written like this, your technology in this aspect is basically a pass.

However, this is not over yet. Although the ActionBar on the top line has been successfully implemented, we have not done the following three tabs: chat, discovery, and address book. Such high-end features cannot be ignored. Therefore, we will explore how to achieve such a Tab effect.

Although I have explained how to create a Tab in ActionBar in the previous article, I am not going to use it here, because it is not flexible enough and it is difficult to make the same Tab effect. There are also many alternatives to the ActionBar Tab. we can write it by ourselves or use the existing open-source framework on the Internet. The PagerSlidingTabStrip framework is quite good. It is simple and stable here, we can use it directly.

PagerSlidingTabStrip is an open-source framework on GitHub written by Andreas Stuetz. It can basically accomplish similar functions as ActionBar Tab. However, because it is completely open-source, we can modify the code at will, therefore, the scalability is very good.

First, download the source code of PagerSlidingTabStrip and integrate it into our project. The GitHub Homepage Address of PagerSlidingTabStrip is:Https://github.com/astuetz/PagerSlidingTabStrip.

The specific integration method is believed to be the same as that of SlidingMenu and Universal-Image-Loader. I will not repeat it here. Note that the native code of PagerSlidingTabStrip cannot achieve the same effect as that of the original code. We need to modify the source code. However, because the source code of PagerSlidingTabStrip is long, I will not post the modified code. You can download the WeChatSample source code. Here you can find the modified PagerSlidingTabStrip code.

After integration, you need to write the function. modify the code in activity_main.xml.xml (the layout file corresponding to MainActivity), as shown below:

      
       
   
  
It is relatively simple. There are two controls, PagerSlidingTabStrip at the top, and ViewPager under PagerSlidingTabStrip.

 

Create ChatFragment, FoundFragment, and ContactsFragment, which correspond to the chat, discovery, and address book interfaces respectively. In Fragment, you only need to place a TextView to indicate this interface. ChatFragment is shown as follows:

Public class ChatFragment extends Fragment {@ Overridepublic View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {LayoutParams params = new LayoutParams (LayoutParams. MATCH_PARENT, LayoutParams. MATCH_PARENT); FrameLayout fl = new FrameLayout (getActivity (); fl. setLayoutParams (params); DisplayMetrics dm = getResources (). getDisplayMetrics (); final int margin = (int) TypedValue. applyDimension (TypedValue. COMPLEX_UNIT_DIP, 8, dm); TextView v = new TextView (getActivity (); params. setMargins (margin, margin); v. setLayoutParams (params); v. setLayoutParams (params); v. setGravity (Gravity. CENTER); v. setText (chat interface); v. setTextSize (int) TypedValue. applyDimension (TypedValue. COMPLEX_UNIT_SP, 12, dm); fl. addView (v); return fl ;}}
FoundFragment is as follows:
Public class FoundFragment extends Fragment {@ Overridepublic View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {LayoutParams params = new LayoutParams (LayoutParams. MATCH_PARENT, LayoutParams. MATCH_PARENT); FrameLayout fl = new FrameLayout (getActivity (); fl. setLayoutParams (params); DisplayMetrics dm = getResources (). getDisplayMetrics (); final int margin = (int) TypedValue. applyDimension (TypedValue. COMPLEX_UNIT_DIP, 8, dm); TextView v = new TextView (getActivity (); params. setMargins (margin, margin); v. setLayoutParams (params); v. setLayoutParams (params); v. setGravity (Gravity. CENTER); v. setText (Discovery Interface); v. setTextSize (int) TypedValue. applyDimension (TypedValue. COMPLEX_UNIT_SP, 12, dm); fl. addView (v); return fl ;}}
ContactsFragment is as follows:
Public class ContactsFragment extends Fragment {@ Overridepublic View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {LayoutParams params = new LayoutParams (LayoutParams. MATCH_PARENT, LayoutParams. MATCH_PARENT); FrameLayout fl = new FrameLayout (getActivity (); fl. setLayoutParams (params); DisplayMetrics dm = getResources (). getDisplayMetrics (); final int margin = (int) TypedValue. applyDimension (TypedValue. COMPLEX_UNIT_DIP, 8, dm); TextView v = new TextView (getActivity (); params. setMargins (margin, margin); v. setLayoutParams (params); v. setLayoutParams (params); v. setGravity (Gravity. CENTER); v. setText (Address Book Interface); v. setTextSize (int) TypedValue. applyDimension (TypedValue. COMPLEX_UNIT_SP, 12, dm); fl. addView (v); return fl ;}}
Finally, modify the code in MainActivity and add the PagerSlidingTabStrip configuration, as shown below:
Public class MainActivity extends FragmentActivity {/*** Fragment */private ChatFragment chatFragment;/*** Fragment */private FoundFragment foundFragment; /*** Fragment */private ContactsFragment contactsFragment on the address book interface;/*** PagerSlidingTabStrip instance */private PagerSlidingTabStrip tabs; /*** get the density of the current screen */private DisplayMetrics dm; @ Overrideprotected void onCreate (Bundle savedInstanceState) {Super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); setOverflowShowingAlways (); dm = getResources (). getDisplayMetrics (); ViewPager pager = (ViewPager) findViewById (R. id. pager); tabs = (PagerSlidingTabStrip) findViewById (R. id. tabs); pager. setAdapter (new MyPagerAdapter (getSupportFragmentManager (); tabs. setViewPager (pager); setTabsValue ();}/*** assigns values to attributes of PagerSlidingTabStrip. */Private void setTabsValue () {// set the Tab to automatically fill the tabs with the full screen. setShouldExpand (true); // set the Tab line to transparent tabs. setDividerColor (Color. TRANSPARENT); // set the height of the line at the bottom of the Tab. setUnderlineHeight (int) TypedValue. applyDimension (TypedValue. COMPLEX_UNIT_DIP, 1, dm); // sets the height of the Tab Indicator tabs. setIndicatorHeight (int) TypedValue. applyDimension (TypedValue. COMPLEX_UNIT_DIP, 4, dm); // set the text size of the Tab title tabs. setTextSize (int) TypedValue. applyDimension (TypedValue. COMPLEX_UNIT_SP, 16, dm); // sets the color of Tab Indicator tabs. setIndicatorColor (Color. parseColor (# 45c01a); // sets the color of the Selected Tab text (this is a custom method) tabs. setSelectedTextColor (Color. parseColor (# 45c01a); // deselect the background color tabs when you click Tab. setTabBackground (0);} public class MyPagerAdapter extends FragmentPagerAdapter {public MyPagerAdapter (FragmentManager fm) {super (fm);} private final String [] titles = {chat, found, address book }; @ Overridepublic CharSequence getPageTitle (int position) {return titles [position] ;}@ Overridepublic int getCount () {return titles. length ;}@ Overridepublic Fragment getItem (int position) {switch (position) {case 0: if (chatFragment = null) {chatFragment = new ChatFragment ();} return chatFragment; case 1: if (foundFragment = null) {foundFragment = new FoundFragment ();} return foundFragment; case 2: if (contactsFragment = null) {contactsFragment = new ContactsFragment ();} return contactsFragment; default: return null ;}}}......}
The configuration is also relatively simple. We can see that we first obtain the PagerSlidingTabStrip and ViewPager instances in the onCreate () method, and then set an Adapter for ViewPager, the ChatFragment, FoundFragment, and ContactsFragment interfaces are stored in the Adapter. This allows you to slide between chat, discovery, and address book interfaces.

 

Set the ViewPager instance to PagerSlidingTabStrip, and then call the setTabsValue () method to configure the details of PagerSlidingTabStrip to achieve the same effect as that of the Tab. Each attribute has a description in the code. I will not explain it here. Note that the setSelectedTextColor () method is self-defined, because PagerSlidingTabStrip does not support highlighting the title of the Selected Tab, but it has this effect, therefore, I have modified the source code of PagerSlidingTabStrip here. If you are looking at the native PagerSlidingTabStrip code, you will not be able to find this method.
Now, all the code has been written. Let's run it to see the effect, as shown in:

Well, the effect is quite good. Isn't it too much for the title to be a high imitation main interface? After studying the three articles before and after, I believe that everyone has mastered the ActionBar technology very well, so our ActionBar series articles will end here.

Well, today's explanation is here. If you have any questions, you can leave a message below.

Click here to download the source code

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.