This is the 19th day of my participation in the Gwen Challenge in November. Check out the details: The last Gwen Challenge in 2021

The effect of the implementation:

To achieve this linkage effect, you need to use CoordinatorLayout, which is a control specifically designed for linkage. In this effect, we first learn the use of TabLayout.

First, the basic use of TabLayout

public class TabLayout extends HorizontalScrollView
Copy the code

As you can see, the HorizontalScrollView control is a descendant of the HorizontalScrollView control. That’s what we use to implement our top Tab page.

2. Common attributes.

  • App :tabIndicatorColor: Indicates the color of the Tab page indicator
  • App :tabSelectedTextColor: The color of the Tab page when selected
  • App :tabTextColor: Color of the text on the Tab page
  • App :tabMode: displays Tab pages in two forms: MODE_FIXED and MODE_SCROLLABLE. Fixed is the fill mode, which is the default mode. It means that TabLayout cannot be scrolled, and there is a maximum width within which all tabs are squeezed. MODE_SCROLLABLE can be scrolled without crowding together.

3. Basic Use:

To use TabLayout, you need to add Tab pages. The Tab class is a static inner class of TabLayout, and its constructors are package accessible, meaning that you cannot construct an instance externally, only through TabLayout’s newTab method.

4. Simple use:

	tabLayout = (TabLayout) findViewById(R.id.tabs);

    TabLayout.Tab tabFirst = tabLayout.newTab();
    tabFirst.setText("TabFirst");
    tabLayout.addTab(tabFirst);

    TabLayout.Tab tabSecond = tabLayout.newTab();
    tabSecond.setText("tabSecond");
    tabLayout.addTab(tabSecond);

    TabLayout.Tab tabThird = tabLayout.newTab();
    tabThird.setText("tabThird");
    tabLayout.addTab(tabThird);
Copy the code

Effect:

One is the effect on the real phone of my phone, the other is the effect on the emulator, the same version of API17, I don’t know why the effect is so different.

#####5, TabLayout combined with ViewPager use if you can bind TabLayout with ViewPager that effect beautiful people can not imagine, in also do not have so complex processing Indicator. TabLayout already gives us the setupWithViewPager method to bind to.

(1) First look at the layout file:

	<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" android:fitsSystemWindows="true"
	    tools:context=".MainActivity">
	
	    <android.support.design.widget.AppBarLayout
	        android:layout_height="wrap_content"
	        android:layout_width="match_parent"
	        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
	
	        <android.support.v7.widget.Toolbar
	            android:id="@+id/toolbar"
	            android:layout_width="match_parent"
	            android:layout_height="?attr/actionBarSize"
	            android:background="?attr/colorPrimary"
	            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
	            app:layout_scrollFlags="scroll|enterAlways"/>
	        <android.support.design.widget.TabLayout
	            android:id="@+id/tabs"
	            android:layout_width="match_parent"
	            android:layout_height="wrap_content"
	            app:tabIndicatorColor="#FF0000"
	            app:tabSelectedTextColor="#00FF00"
	            app:tabTextColor="#FFFFFF"
	            app:tabMode="fixed"/>
	    </android.support.design.widget.AppBarLayout>
	
	    <android.support.v4.view.ViewPager
	        android:id="@+id/viewPager"
	        android:layout_height="match_parent"
	        android:layout_width="match_parent"
	        app:layout_behavior="@string/appbar_scrolling_view_behavior"
	        />
	
	    <android.support.design.widget.FloatingActionButton android:id="@+id/fab"
	        android:layout_width="wrap_content" android:layout_height="wrap_content"
	        android:layout_gravity="bottom|end" android:layout_margin="@dimen/fab_margin"
	        android:src="@android:drawable/ic_dialog_email"
	        app:borderWidth="0dp"/>
	
	</android.support.design.widget.CoordinatorLayout>
Copy the code

(2) Process in MainActivity.

public class MainActivity extends AppCompatActivity { private ViewPager viewPager; private TabLayout tabLayout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) .setAction("Action", null).show(); }}); viewPager = (ViewPager) findViewById(R.id.viewPager); viewPager.setAdapter(new PagerAdapter() { @Override public int getCount() { return 3; } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public Object instantiateItem(ViewGroup container, int position) { container.addView(new ListViewLayout(getApplication()), position); return container.getChildAt(position); } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeViewAt(position); }}); initTabLayout(); } private void initTabLayout(){ tabLayout = (TabLayout) findViewById(R.id.tabs); TabLayout.Tab tabFirst = tabLayout.newTab(); tabFirst.setText("TabFirst"); tabLayout.addTab(tabFirst); TabLayout.Tab tabSecond = tabLayout.newTab(); tabSecond.setText("tabSecond"); tabLayout.addTab(tabSecond); TabLayout.Tab tabThird = tabLayout.newTab(); tabThird.setText("tabThird"); tabLayout.addTab(tabThird); tabLayout.setupWithViewPager(viewPager); } @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); }}Copy the code

In the previous example we used a View View with a ListView to populate the ViewPager. Take a look at the renderings.

We did, but we didn’t have the Tab page title. Why is that? We need to look at setupWithViewPager(ViewPager ViewPager) source code.

public void setupWithViewPager(ViewPager viewPager) { PagerAdapter adapter = viewPager.getAdapter(); if(adapter == null) { throw new IllegalArgumentException("ViewPager does not have a PagerAdapter set"); } else { this.setTabsFromPagerAdapter(adapter); viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(this)); this.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(viewPager)); }}Copy the code

This method first checks whether the Adapter of the viewPager is null and throws an exception if it is. So before we use this method, we should set the Adapter for the viewPager. Then we look at this. SetTabsFromPagerAdapter (adapter) this method.

public void setTabsFromPagerAdapter(PagerAdapter adapter) { this.removeAllTabs(); int i = 0; for(int count = adapter.getCount(); i < count; ++i) { this.addTab(this.newTab().setText(adapter.getPageTitle(i))); }}Copy the code

In this method, remove all Tab pages using the removeAllTabs() method, and then traverse the Adapter to generate a Tab page, where the adapter getPageTitle method is called to set the Tab page name. So our Adapter needs to override the getPageTitle method.

Because we didn’t override the method, the title doesn’t show up. Similarly, we don’t need to manually add TAB pages, just check in the getPageTitle method.

Modified:

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) .setAction("Action", null).show(); }}); viewPager = (ViewPager) findViewById(R.id.viewPager); viewPager.setAdapter(new PagerAdapter() { @Override public int getCount() { return 3; } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public Object instantiateItem(ViewGroup container, int position) { container.addView(new ListViewLayout(getApplication()), position); return container.getChildAt(position); } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeViewAt(position); } @override public CharSequence getPageTitle(int position) {if (position % 3 == 0) {return "newworld "; } else if (position % 3 == 1) {return "IT news "; } else {return "Mr_dsw blog "; }}}); tabLayout = (TabLayout) findViewById(R.id.tabs); tabLayout.setupWithViewPager(viewPager); }Copy the code

This is what the renderings look like.

Second, the basic use of CoordinatorLayout

(1) app:layout_scrollFlags: it has four values, respectively:

  • Scroll: All views that want to scroll out of the screen need to set this flag. Views without this flag will be fixed at the top of the screen. For example, TabLayout does not set this value and will stay at the top of the screen.
  • EnterAlways: When this flag is set, scrolling down causes the view to become visible, enabling quick “return mode”.
  • EnterAlwaysCollapsed: When your views have the minHeight attribute set and use this flag, your views enter at the minimum height and expand to the full height only when the scrolling view reaches the top.
  • ExitUntilCollapsed: Rolls out of the screen and collapses at the top.

(2) app:layout_behavior: In order for the ToolBar to scroll, CoordinatorLayout puts a scrollable View in it. The CoordinatorLayout includes a child View that has a scrollable View that needs to set the app:layout_behavior property.

But we set this property but still can not achieve the need to scale, then nothing, I changed the ListView to RecyclerView, can actually scroll, I don’t know what the situation.

Look at the RecycerView layout:

<? The XML version = "1.0" encoding = "utf-8"? > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbars="vertical" /> </LinearLayout>Copy the code

Let’s customize a View.

	/**
	 * Created by dsw on 2015/11/8.
	 */
	public class RecyclerViewLayout extends LinearLayout {
	    public RecyclerViewLayout(Context context, AttributeSet attrs) {
	        super(context, attrs);
	        initView(context);
	    }
	
	    public RecyclerViewLayout(Context context) {
	        super(context);
	        initView(context);
	    }
	
	    private void initView(Context context){
	        View view = LayoutInflater.from(context).inflate(R.layout.recycler_view,this);
	        RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
	        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
	        recyclerView.setAdapter(new MyAdapter(context));
	    }
	
	    class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder>{
	        String[] data = new String[]{"A","B","C","D","E",
	                "F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","Z","Y","Z"};
	        Context context;
	        public MyAdapter(Context context){
	            this.context = context;
	        }
	        @Override
	        public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
	            TextView textView = new TextView(context);
	            textView.setTextColor(Color.parseColor("#000000"));
	            textView.setTextSize(17*getResources().getDisplayMetrics().scaledDensity);
	            textView.setPadding(20,20,20,20);
	            return new MyViewHolder(textView);
	        }
	
	        @Override
	        public void onBindViewHolder(MyViewHolder holder, int position) {
	            holder.tv_textView.setText(data[position]);
	        }
	
	        @Override
	        public int getItemCount() {
	            return data.length;
	        }
	
	        public class MyViewHolder extends RecyclerView.ViewHolder{
	            public TextView tv_textView;
	            public MyViewHolder(View itemView) {
	                super(itemView);
	                tv_textView = (TextView) itemView;
	            }
	        }
	    }
	}
Copy the code

We just need to modify it in the PagerAdapter.

	 @Override
    public Object instantiateItem(ViewGroup container, int position) {
        container.addView(new RecyclerViewLayout(getApplication()), position);
        return container.getChildAt(position);
    }
Copy the code

That will do. Effect:

Take a look at the monster in the simulator!