需求分析

  • 在Activity中显示如下效果

图1

1) 界面元素如图1所示

2) 点击”人物“,文字和图片都会相应改变,如图2所示。点击”动物“和”植物“时,效果类似。

图2

(3) 点击“Click我,传data给Activity”按钮,首先实现按钮本身的按压效果,并修改上方TextView的内容为“Animal from fragment。如图3所示。
提示:按钮在fragment类中,TextView在Activity类中

图3

设计

Activity布局

image-20220406093348784

  • 这里要用动态方式引入fragment …….</FramLayout>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<?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">
<TextView
android:id="@+id/textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="26sp"
android:text="这里之后用Java代码动态填写"
android:gravity="center"
android:paddingVertical="30dp"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/fl_container">
</FrameLayout>
<RadioGroup
android:id="@+id/radiogroup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:checkedButton="@id/rg_person"
android:orientation="horizontal">
<RadioButton
android:id="@+id/rg_person"
style="@style/flRadioButton"
android:text="人物"
android:textColor="@drawable/fl_rb_textcolor"
android:drawableTop="@drawable/fl_person_bg"
/>
<RadioButton
android:id="@+id/rg_animal"
style="@style/flRadioButton"
android:text="动物"
android:textColor="@drawable/fl_rb_textcolor2"
android:drawableTop="@drawable/fl_animal_bg"
/>
<RadioButton
android:id="@+id/rg_plant"
style="@style/flRadioButton"
android:textColor="@drawable/fl_rb_textcolor3"
android:drawableTop="@drawable/fl_plant_bg"
android:text="植物"

/>
</RadioGroup>

</LinearLayout>
  • 在values目录下创建flRadioButton.xml文件,编写统一的样式,减少重复代码
1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="flRadioButton">
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">match_parent</item>
<item name="android:layout_weight">1</item>
<item name="android:textSize">24sp</item>
<item name="android:gravity">center</item>
<item name="android:layout_marginTop">10dp</item>
<item name="android:layout_marginBottom">10dp</item>
<item name="android:button">@null</item>
</style>
</resources>
  • 在drawble目录下创建并分别编写人物,动物,植物点击变化的图标,文字变化的xml文件,这里只给出一个样例。
1
2
3
4
5
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:drawable="@mipmap/plant2"/>
<item android:state_checked="false" android:drawable="@mipmap/plant"/>
</selector>
  • Button样例的修改,必须修改themes.xml文件里的parent属性才能显示自定义效果
1
<style name="Theme.DialogTestApplication" parent="Theme.AppCompat.DayNight.DarkActionBar">

Fragment布局

  • 新建三个fragment文件(PersonFragment,PlantFragment,AnimalFragment)后,先对其对应xml文件进行设计

image-20220406094202201

  • 三个fragment布局基本相同,这里给出一个样例。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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=".fragment.PersonFragment">

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<Button
android:id="@+id/fl_btn_person"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
android:background="@drawable/button_bg"
android:paddingVertical="25dp"
android:text="Click我,传data给Activity"
android:textAllCaps="false"
android:textSize="24sp"></Button>

<ImageView
android:layout_below="@id/fl_btn_person"
android:id="@+id/fl_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
</FrameLayout>

Activtity和Fragment交互

  • 这里为了更好理解Activity和Fragment传值的方式,我先在Activity中把值传到Fragment中

  • 然后再把Fragment中获得的值通过回调接口传回Activity中,最后在textview中显示出来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package com.gallifrey.fragmnettestapplication;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;

import android.os.Bundle;
import android.widget.RadioGroup;
import android.widget.TextView;

import com.gallifrey.fragmnettestapplication.fragment.AnimalFragment;
import com.gallifrey.fragmnettestapplication.fragment.PersonFragment;
import com.gallifrey.fragmnettestapplication.fragment.PlantFragment;

import java.util.LinkedList;

public class MainActivity extends AppCompatActivity implements PersonFragment.PersonCallBack, PlantFragment.PlantCallBack, AnimalFragment.AnimalCallBack {
private FragmentManager fragmentManager;
private FragmentTransaction fragmentTransaction;
private RadioGroup mRg;
private LinkedList<Fragment> linkedList;
private PersonFragment personFragment;
private PlantFragment plantFragment;
private AnimalFragment animalFragment;
private TextView textView;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

linkedList=new LinkedList<>();
textView=findViewById(R.id.textview);
mRg=findViewById(R.id.radiogroup);
fragmentManager=getSupportFragmentManager();


/**这里为了更好理解Activity和Fragment传值的方式
* 我先在Activity中把值传到Fragment中
* 然后再把Fragment中获得的值通过回调接口传回Activity中
* 最会在textview中显示出来
* */
mRg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
switch (i){
case R.id.rg_person:
if(personFragment==null){
personFragment=PersonFragment.newInstance("person from fragment");//创建对象,传参
linkedList.add(personFragment);//加入列表
hideOtherFragment(personFragment,true);//第一次加入,添加到activity
}else{
hideOtherFragment(personFragment,false);//直接隐藏
}
break;
case R.id.rg_plant:
if(plantFragment==null){
plantFragment=PlantFragment.newInstance("plant from fragment");//创建对象,传参
linkedList.add(plantFragment);//加入列表
hideOtherFragment(plantFragment,true);//第一次加入,添加到activity
}else{
hideOtherFragment(plantFragment,false);//直接隐藏
}
break;
case R.id.rg_animal:
if(animalFragment==null){
animalFragment=AnimalFragment.newInstance("animal from fragment");//创建对象,传参

linkedList.add(animalFragment);//加入列表
hideOtherFragment(animalFragment,true);//第一次加入,添加到activity
}else{
hideOtherFragment(animalFragment,false);//直接隐藏
}
break;
}
}
});
}




//隐藏其他fragment
private void hideOtherFragment(Fragment currentFragment, boolean b){
fragmentTransaction=fragmentManager.beginTransaction();//创建事务
if(b) {
fragmentTransaction.add(R.id.fl_container, currentFragment);//如果从未加入,则将当前Fragment添加到activity
}
//遍历列表
for(Fragment tempFragment:linkedList){
//如果选中,则显示;否则则隐藏
if(tempFragment.equals(currentFragment)){
fragmentTransaction.show(tempFragment);
}else {
fragmentTransaction.hide(tempFragment);
}
}
//提交事务
fragmentTransaction.commitAllowingStateLoss();
}

//同回调接口使得activity的textview获得数据
@Override
public void setData(String str) {
textView.setText(str);
}
}
  • 三个Fragment的写法是一样的,这里给出一个样例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package com.gallifrey.fragmnettestapplication.fragment;

import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;

import com.gallifrey.fragmnettestapplication.R;

public class AnimalFragment extends Fragment {
private ImageView imageView;
private Button button;
private AnimalCallBack animalCallBack;

//让回调接口初始化
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
animalCallBack=(AnimalCallBack) context;
}

//这里只要一个String作为键值对,之后通过回调接口传参数给Activity就可以了
private static final String ARG_PARAM1 = "param1";
private String mParam1;

public AnimalFragment() {
// Required empty public constructor
}


public static AnimalFragment newInstance(String param1) {
AnimalFragment fragment = new AnimalFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
fragment.setArguments(args);
return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);

}


}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {


//这里返回一个view
View view=inflater.inflate(R.layout.fragment_animal, container, false);
//在这里加入监听
imageView=view.findViewById(R.id.fl_image);
imageView.setImageResource(R.drawable.laohu);

button=view.findViewById(R.id.fl_btn_animal);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//这用一个回调接口的方法回调回来
animalCallBack.setData(mParam1);
}
});

return view;
}


//定义一个回调接口
public interface AnimalCallBack{
void setData(String str);
}

}

最终效果

image-20220406095144589

image-20220406095337844

image-20220406095219675

image-20220406095248132