Introduction à cette section :
Dans la section précédente, nous avons acquis une compréhension préliminaire de Fragment, en apprenant les concepts, le cycle de vie, la gestion de Fragment et les transactions de Fragment, ainsi que le chargement dynamique et statique de Fragment. À partir de cette section, nous allons expliquer quelques exemples pratiques de Fragment dans le développement réel ! Ce que cette section explique, c'est la mise en œuvre de la barre de navigation inférieure ! Il existe de nombreuses méthodes de base pour la barre de navigation inférieure, comme l'utilisation de tous les TextView, ou l'utilisation de RadioButton, ou l'utilisation de TabLayout + RadioButton. Bien sûr, pour des situations complexes, vous devez encore utiliser la méthode d'encapsulation des mises en page sur la couche externe ! Dans cette section, nous utilisons TextView pour créer un effet de barre de navigation inférieure et nous nous familiarisons également avec l'utilisation de Fragment ! Très bien, commençons le contenu de cette section !
1. L'image d'effet à atteindre et la structure du répertoire du projet :
Tout d'abord, jetons un coup d'œil à l'image d'effet :

Ensuite, regardons la structure du répertoire de notreprojet:

2. Processus de mise en œuvre :
Étape 1 : Écrire quelques fichiers de ressources pour les options du bas
Nous pouvons voir sur l'image que chaque élément en bas a un effet différent lorsqu'on clique dessus, n'est-ce pas ! Nous déterminons cela par son état 'sélectionné' ! Les fichiers de ressources que nous devons écrire sont : d'abord les images, puis le texte, et enfin l'arrière-plan !
Ressources Drawable d'image :tab_menu_channel.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@mipmap/tab_channel_pressed" android:state_selected="true" />
<item android:drawable="@mipmap/tab_channel_normal" />
</selector>
Pour les trois autres, suivez simplement le même modèle !
Ressources de texte :tab_menu_text.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/text_yellow" android:state_selected="true" />
<item android:color="@color/text_gray" />
</selector>
Ressources d'arrière-plan :tab_menu_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true">
<shape>
<solid android:color="#FFC4C4C4" />
</shape>
</item>
<item>
<shape>
<solid android:color="@color/transparent" />
</shape>
</item>
</selector>
Étape 2 : Écrire notre mise en page d'Activity
activity_main.xml:
<RelativeLayout 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"
tools:context=".MainActivity">
<RelativeLayout
android:id="@+id/ly_top_bar"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="@color/bg_topbar">
<TextView
android:id="@+id/txt_topbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:gravity="center"
android:textSize="18sp"
android:textColor="@color/text_topbar"
android:text="信息"/>
<View
android:layout_width="match_parent"
android:layout_height="2px"
android:background="@color/div_white"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
<LinearLayout
android:id="@+id/ly_tab_bar"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_alignParentBottom="true"
android:background="@color/bg_white"
android:orientation="horizontal">
<TextView
android:id="@+id/txt_channel"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/tab_menu_bg"
android:drawablePadding="3dp"
android:drawableTop="@drawable/tab_menu_channel"
android:gravity="center"
android:padding="5dp"
android:text="@string/tab_menu_alert"
android:textColor="@drawable/tab_menu_text"
android:textSize="16sp" />
<TextView
android:id="@+id/txt_message"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/tab_menu_bg"
android:drawablePadding="3dp"
android:drawableTop="@drawable/tab_menu_message"
android:gravity="center"
android:padding="5dp"
android:text="@string/tab_menu_profile"
android:textColor="@drawable/tab_menu_text"
android:textSize="16sp" />
<TextView
android:id="@+id/txt_better"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/tab_menu_bg"
android:drawablePadding="3dp"
android:drawableTop="@drawable/tab_menu_better"
android:gravity="center"
android:padding="5dp"
android:text="@string/tab_menu_pay"
android:textColor="@drawable/tab_menu_text"
android:textSize="16sp" />
<TextView
android:id="@+id/txt_setting"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/tab_menu_bg"
android:drawablePadding="3dp"
android:drawableTop="@drawable/tab_menu_setting"
android:gravity="center"
android:padding="5dp"
android:text="@string/tab_menu_setting"
android:textColor="@drawable/tab_menu_text"
android:textSize="16sp"/>
</LinearLayout>
<View
android:id="@+id/div_tab_bar"
android:layout_width="match_parent"
android:layout_height="2px"
android:background="@color/div_white"
android:layout_above="@id/ly_tab_bar"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/ly_top_bar"
android:layout_above="@id/div_tab_bar"
android:id="@+id/ly_content">
</FrameLayout>
</RelativeLayout>
Analyse du code :
Définissez d'abord le style de la barre de titre supérieure. Ajoutez un TextView au milieu d'un LinearLayout de 48dp comme titre !
Ensuite, définissez un LinearLayout d'une taille de 56dp aligné en bas. Ajoutez-y quatre TextView avec un ratio de 1:1:1:1, et définissez les propriétés pertinentes. Ajoutez ensuite un segment de ligne à ce LinearLayout !
Enfin, en utilisant la barre de titre et la barre de navigation inférieure comme limites, écrivez un FrameLayout avec une largeur et une hauteur définies sur match_parent, à utiliser comme conteneur pour le Fragment !
PS :Les attributs des quatre TextView ici sont répétitifs. Vous pouvez aussi les extraire vous-même, écrire un style et le définir~
Étape 3 : Masquer la barre de navigation supérieure
J'ai découvert de manière inattendue qu'appeler précédemment dans ActivityrequestWindowFeature(Window.FEATURE_NO_TITLE)peut masquer la barre de navigation supérieure intégrée du téléphone, mais en écrivant la démo, j'ai constaté que cela signalait une erreur, même si cette instruction était écrite avant setContentView() ! Cela peut être parce qu'il hérite d'AppCompatActivity au lieu de la classe Activity !
Bien sûr, l'appel précédent à getSupportActionbar().hide() masque l'Actionbar, mais elle sera toujours sur l'interface ! Enfin, il existe une autre méthode, qui consiste à écrire vous-même un style, puis à définir ce thème pour l'Application dans AndroidManifest.xml :
Remarque :Placez requestWindowFeature(Window.FEATURE_NO_TITLE); avant super.onCreate(savedInstanceState); pour masquer l'ActionBar sans signaler d'erreur.
EnsuiteAndroidManifest.xmldéfinissez l'attribut theme :
android:theme="@style/Theme.AppCompat.NoActionBar"
PS :Le « code de conscience » ci-dessus est sponsorisé par Cao Shen de Good Programmer~
Étape 4 : Créer un layout simple et une classe pour un Fragment :
fg_content.xml:
<?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:background="@color/bg_white">
<TextView
android:id="@+id/txt_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="呵呵"
android:textColor="@color/text_yellow"
android:textSize="20sp"/>
</LinearLayout>
MyFragment.java:
/**
* Created by Coder-pig on 2015/8/28 0028.
*/
public class MyFragment extends Fragment {
private String content;
public MyFragment(String content) {
this.content = content;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fg_content,container,false);
TextView txt_content = (TextView) view.findViewById(R.id.txt_content);
txt_content.setText(content);
return view;
}
}
Analyse du code :
Il redéfinit simplement la méthode onCreateView(). Les autres méthodes peuvent être redéfinies selon les besoins !
Étape 5 : écrire MainActivity.java
Tout d'abord, parlons de quelques points clés que nous devons prendre en compte :
- Quand un Fragment doit-il être initialisé et ajouté au conteneur ? Quand doit-il être masqué et affiché ?
- Comment faire pour qu'un TextView soit sélectionné ? Après avoir sélectionné un TextView, quelles opérations faut-il effectuer ?
- Lorsque l'on vient d'entrer dans MainActivity, comment faire pour qu'un TextView soit dans l'état sélectionné ?
Eh bien, répondons maintenant aux questions ci-dessus une par une :
- Après avoir sélectionné un TextView, nous vérifions si le Fragment correspondant est null. S'il est null, nous l'initialisons et l'ajoutons au conteneur. Quant à masquer, nous définissons une méthode pour masquer tous les Fragments. Chaque fois qu'un événement de clic est déclenché, on appelle d'abord cette méthode hideAll pour masquer tous les Fragments, puis si le Fragment correspondant au TextView n'est pas null, nous affichons ce Fragment ;
- Nous implémentons cela via l'événement de clic. Après avoir cliqué sur un TextView, on réinitialise d'abord l'état sélectionné de tous les TextView à false, puis on définit l'état sélectionné du TextView cliqué à true ;
- C'est encore plus simple. Nous définissons la sélection via l'événement de clic, donc il suffirait d'ajouter une méthode dans la méthode onCreate() pour déclencher l'événement de clic, non~txt_channel.performClick();
Une fois que vous avez compris la logique, passons directement au code :
MainActivity.java:
/**
* Created by Coder-pig on 2015/8/28 0028.
*/
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
//UI Object
private TextView txt_topbar;
private TextView txt_channel;
private TextView txt_message;
private TextView txt_better;
private TextView txt_setting;
private FrameLayout ly_content;
//Fragment Object
private MyFragment fg1,fg2,fg3,fg4;
private FragmentManager fManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
fManager = getFragmentManager();
bindViews();
txt_channel.performClick(); //模拟一次点击,既进去后选择第一项
}
//UI组件初始化与事件绑定
private void bindViews() {
txt_topbar = (TextView) findViewById(R.id.txt_topbar);
txt_channel = (TextView) findViewById(R.id.txt_channel);
txt_message = (TextView) findViewById(R.id.txt_message);
txt_better = (TextView) findViewById(R.id.txt_better);
txt_setting = (TextView) findViewById(R.id.txt_setting);
ly_content = (FrameLayout) findViewById(R.id.ly_content);
txt_channel.setOnClickListener(this);
txt_message.setOnClickListener(this);
txt_better.setOnClickListener(this);
txt_setting.setOnClickListener(this);
}
//重置所有文本的选中状态
private void setSelected(){
txt_channel.setSelected(false);
txt_message.setSelected(false);
txt_better.setSelected(false);
txt_setting.setSelected(false);
}
//隐藏所有Fragment
private void hideAllFragment(FragmentTransaction fragmentTransaction){
if(fg1 != null)fragmentTransaction.hide(fg1);
if(fg2 != null)fragmentTransaction.hide(fg2);
if(fg3 != null)fragmentTransaction.hide(fg3);
if(fg4 != null)fragmentTransaction.hide(fg4);
}
@Override
public void onClick(View v) {
FragmentTransaction fTransaction = fManager.beginTransaction();
hideAllFragment(fTransaction);
switch (v.getId()){
case R.id.txt_channel:
setSelected();
txt_channel.setSelected(true);
if(fg1 == null){
fg1 = new MyFragment("第一个Fragment");
fTransaction.add(R.id.ly_content,fg1);
}else{
fTransaction.show(fg1);
}
break;
case R.id.txt_message:
setSelected();
txt_message.setSelected(true);
if(fg2 == null){
fg2 = new MyFragment("第二个Fragment");
fTransaction.add(R.id.ly_content,fg2);
}else{
fTransaction.show(fg2);
}
break;
case R.id.txt_better:
setSelected();
txt_better.setSelected(true);
if(fg3 == null){
fg3 = new MyFragment("第三个Fragment");
fTransaction.add(R.id.ly_content,fg3);
}else{
fTransaction.show(fg3);
}
break;
case R.id.txt_setting:
setSelected();
txt_setting.setSelected(true);
if(fg4 == null){
fg4 = new MyFragment("第四个Fragment");
fTransaction.add(R.id.ly_content,fg4);
}else{
fTransaction.show(fg4);
}
break;
}
fTransaction.commit();
}
}
3. Téléchargement du code :
FragmentDemo.zip:Téléchargement de FragmentDemo.zip Déclaration: Les ressources d'images proviennent de l'application :better, ce code est uniquement à des fins de démonstration et n'est pas utilisé à des fins commerciales !
4. Résumé de cette section
Cette section a expliqué comment utiliser un LinearLayout + quatre TextView pour implémenter une barre de navigation inférieure et la logique d'add, hide et show de Fragment~ C'est encore assez simple. Enfin, je tiens à remercier Ji Shen, B Shen de la Piggy's Secret Base, et Cao Shen de Good Programmer pour leurs conseils ! Mille mercis. Cet article est dédié à commémorer le retour de Piggy dans le monde de la frime, eh bien, le retour à la couche application. Héhé, c'est tout pour cette section, merci~