I will post to Qiita for the first time! Until now, I have seen many people's articles and studied a lot, but I will try to write articles that will be helpful to many people, so thank you.
As for the main subject, when using TabLayout, I wanted to call the Fragment method by clicking the Toolbar menu of Activity, but I couldn't find the page that was written in an easy-to-understand manner, so I will summarize it. First, I will introduce a simple tab implementation using TabLayout and ViewPager. There are many articles that introduce the implementation of tabs, but in this article I will consider Material Design and make it. In the next article, I will summarize how to operate Fragment from Activity and how to operate Activity from Fragment.
The height of the Toolbar's shadow (elevation) in Material Design is 4dp. You can also use @ dimen / abc_action_bar_elevation_material. Elevation & shadows - Material Design
values/styles.xml
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
tools:context="...MainActivity">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
app:title="Tab Sample"
app:titleTextColor="@color/white"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
style="@style/MyCustomTabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:elevation="4dp" />
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</LinearLayout>
@ style / MyCustomTabLayout is an original style that changes the text color of a tab when it is selected and when it is not selected. In Material Design, the text color of the selected tab is #fff, and the text color of the non-selected tab is #fff / opacity 70%. Tabs - Components - Material Design ARGB color code transparency summary --Qiita
values/styles.xml
<resources>
...
<style name="MyCustomTabLayout" parent="Widget.Design.TabLayout">
<item name="tabTextAppearance">@style/MyCustomTabText</item>
<item name="tabSelectedTextColor">@color/white</item>
</style>
<style name="MyCustomTabText" parent="TextAppearance.AppCompat.Button">
<item name="android:textColor">@color/white_70percent</item>
</style>
</resources>
Fragment Next, create a Fragment. The role of Fragment when implementing tabs can accept user operations by introducing it to ViewPager via Adapter. And every time the tab selection changes, the Fragment displayed by ViewPager will switch, so you need to create as many Fragments as there are tabs. (If multiple tabs require the user to behave in the same way, one Fragment can be implemented with fewer Fragments than the number of tabs by corresponding to multiple tabs.) Fragment is similar to Activity. It consists of a class / java file and a layout / xml file. And since Fragment has a life cycle, it can be used in the same way as Activity. However, be aware that the Fragment life cycle is different from the Activity life cycle.
Main1Fragment.java
package ...;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class Main1Fragment extends Fragment {
public Main1Fragment() {
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_main1, container, false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
}
Main2Fragment.java
package ...;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class Main2Fragment extends Fragment {
public Main2Fragment() {
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_main2, container, false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
}
This is the basic form of Fragment. The OnCreatedView () method returns a View that inflates the Fragment Layout. Also, the onViewCreated () method can be used in the same way as the onCreate () method in Activity. Since the Override original operation is performed by super.onViewCreated (view, savedInstanceState) ;, arbitrary code is described below.
Here, change the Layout of Fragment so that the two Layouts can be distinguished. Now only change the text of the TextView.
layout/fragment_main1.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp"
tools:context="...Main1Fragment">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="fragment1" />
</LinearLayout>
layout/fragment_main2.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp"
tools:context="...Main2Fragment">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="fragment2" />
</LinearLayout>
Adapter Next, create an Adapter. Adapter is a mechanism for introducing Fragment into ViewPager. The Adapter that can be set in ViewPager is an adapter that inherits FragmentPagerAdapter.
OriginalFragmentPagerAdapter.java
package ...;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.view.ViewGroup;
public class OriginalFragmentPagerAdapter extends FragmentPagerAdapter {
private CharSequence[] tabTitles = {"Tab 1", "Tab 2"};
public OriginalFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public CharSequence getPageTitle(int position) {
return tabTitles[position];
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new Main1Fragment();
case 1:
return new Main2Fragment();
default:
return null;
}
}
@Override
public int getCount() {
return tabTitles.length;
}
}
Declare the tab title in an array of type CharSequence. getCount () method: Returns the total number of tabs. getPageTitle () method: The tab titles for the total number of tabs are reflected in the tabs. getItem () method: Reflects the Fragment corresponding to the position. Called every time you select a tab. At that time, it receives a position as an argument, so it returns the Fragment corresponding to that position. Activity Finally, it is the setting of Activity.
MainActivity.java
package ...;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
OriginalFragmentPagerAdapter adapter = new OriginalFragmentPagerAdapter(getSupportFragmentManager());
ViewPager viewPager = findViewById(R.id.viewPager);
viewPager.setOffscreenPageLimit(2);
viewPager.setAdapter(adapter);
TabLayout tabLayout = findViewById(R.id.tabLayout);
tabLayout.setupWithViewPager(viewPager);
}
}
Declare the OriginalFragmentPagerAdapter. You can create an instance by taking FragmentManager as an argument and passing getSupportFragmentManager () when declaring it. Associate ViewPager with the id of layout and set the adapter with the setAdapter () method. The setOffscreenPageLimit () method passes as an argument how many pages before the Fragment should be retained when the user changes the page of ViewPager. For example, if you set this value to 2 in ViewPager that introduced 3 Fragments, the 1st page will be regenerated when you go from page 1 to page 3 and return to page 1. Therefore, if you want to keep the value etc. and prevent it from being reloaded, you need to setOffscreenPageLimit (3). Then, TabLayout is the setupWithViewPager () method, and by setting the ViewPager with the Adapter set, when you click a tab, the Fragment corresponding to that tab will be displayed in the ViewPager.
With the above, you can display the Fragment with a static layout in which the TextView is placed, and you can confirm that the Fragment of the ViewPager can be switched by operating the ViewPager and tabs. Next, it receives the user's operation in Fragment. Let's write a program that creates one EditText and one Button in the Layout of Fragment, receives a character string from EditText when the Button is clicked, and displays it in Toast.
Change the Layout of Fragment.
layout/fragment_main1.xml
<LinearLayout ...>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="fragment1" />
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="text" />
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button_Fragment1" />
</LinearLayout>
Modify the Fragment java file.
Main1Fragment.java
...
public class Main1Fragment extends Fragment {
...
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
final EditText editText = view.findViewById(R.id.editText);
Button button = view.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getContext(), editText.getText().toString(), Toast.LENGTH_LONG).show();
}
});
}
}
To associate the View id of the Layout Layout of Fragment, write it as view.findViewById (R.id ...) in the onViewCreated () method. Since the argument view is the View returned by the OnCreatedView () method when the Fragment was created, the id can be linked from that Layout. Regarding the place where Toast is displayed, the first argument Context of makeText is getContext (). This is where you wrote MainActivity.this, this, getApplicationContext (), etc. in Activity, but you can receive the activity of the parent in which the Fragment is running by writing getContext () in Fragment.
Now you can implement the basic tabs. In the next article Activity to Fragment operation --Qiita , I would like to introduce how to call the Fragment method from Activity. I will.
Recommended Posts