一.实现效果图
这是一个柠檬购买app,实现“柠檬”,“晒单”,“我的”,“消息”4个页面,其中“柠檬”页面可以实现点击具体柠檬出现柠檬的详情加购页面,并且当点击“加入购物车”按钮时,出现“加入成功”页面
app
二.实现原理
1.首先搭建app页面的顶部栏和底部栏
(1)需要创建layout_top.xml和layout_bottom.xml
(2)在layout_top.xml中添加一个TextView控件,设置内容为app的title
(3) 在layout_bottom.xml需要添加4个包含图片的文字的垂直linearlayout,最后大的布局为水平的linearlayout,其中4个垂直的linearlayout需要设置【layout_weight="1"】才能使得4个垂直的linearlayout一样大小
(4)在activity_main.xml文件中,用<include>将layout_top和layout_bottom连接起来,并且中甲设置留白
<include>标签:引用布局代码和实现模块化管理
如:需要设置layout="@layout/layout_top",即将xml文件的名称添加进去,达到引用的作用
2.接着创建4个Fragment和4个activity_tab.xml分别对应4个页面
(1)activity_tab3.xml和activity_tab4.xml较简单,只需要添加一个TextView控件,TextView内容分别设置为“这是我的页面”和“这是消息页面”
(2)为了实现“柠檬”页面可以滑动展示商品,需要创建一个rc_activity_main.xml文件,在该文件里面添加RecyclerView控件,同理”晒单“页面也是如此
2.1 Fragment1的实现(Fragment2同理实现滑动)
(1)需要用3个列表存储展示的图片和数据,然后用map键值对来存储
int[] lemon={R.drawable.p6,R.drawable.p5,R.drawable.p7,R.drawable.p8,R.drawable.p9};
String[] name1={"柠檬树苗","黄柠檬","青柠","香水柠檬","泰国柠檬"};
String[] price1={"20¥","30¥","40¥","50¥","80¥"};
list1=new ArrayList<>();
for(int i=0;i<lemon.length;i++)
{
Map<String,Object> map=new HashMap<>();
map.put("object",lemon[i]);
map.put("name",name1[i]);
map.put("price",price1[i]);
list1.add(map);
}
(2)创建Fragment1的适配器adapter以及adapter中展示的模块页面layout_item.xml文件
(2.1)在adapter里需要创建MyViewHolder,ViewHolder
模式可以缓存每个列表项的视图组件,达到封装和初始化视图组件
(2.2)创建完MyViewHolder后,创建onBindViewHolder,来获取Fragment1传的展示数据
(2.3)实现Fragment1的页面点击跳转,需要使用setOnClickListener函数,
public adapter(Context context, List<Map<String,Object>>
list) {
this.list = list;
this.context=context;
}
@Override
public adapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
inflater = LayoutInflater.from(context).inflate(R.layout.layout_item,viewGroup,false);
MyViewHolder myviewholder =new MyViewHolder(inflater);
return myviewholder;
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int j) {
Map<String,Object> currentItem =list.get(j);
holder.imageview.setImageResource((Integer) currentItem.get("object"));
//holder.textView1.setText(list.get(j).get("name").toString()); // 通过 holder 访问 textView
String str1=list.get(j).get("name").toString();
String str2=list.get(j).get("price").toString();
holder.textView2.setText(str1);
holder.textView3.setText(str2);
holder.imageview.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent(context, Activity_context_detail.class);
intent.putExtra("name",str1);
intent.putExtra("price",str2);
context.startActivity(intent);
//launcher.launch(intent);
}
});
}
@Override
public int getItemCount() {
return list.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView textView2,textView3;
ImageView imageview;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
imageview=itemView.findViewById(R.id.imageView);
textView2 = itemView.findViewById(R.id.rc_textView2);
textView3 = itemView.findViewById(R.id.rc_textView3);
}
}
}
其中用Intent来传参——Intent不仅用于启动组件,还可以在组件之间传递数据。通过在Intent中附加额外的数据(如字符串、整数、布尔值等),可以在发送方和接收方之间共享信息
-
组件间通信:Intent是Android组件(如Activity、Service、BroadcastReceiver等)之间进行通信的核心机制。通过显式或隐式Intent,可以在不同组件之间传递信息和数据。
-
显式Intent:显式Intent明确指定目标组件的类名或包名,用于精确控制组件间的跳转和数据传递。
-
隐式Intent:隐式Intent通过Action、Category和Data等属性来匹配目标组件,实现更灵活的组件间通信。
-
数据传递:Intent可以携带数据,通过putExtra方法添加数据,接收方通过getIntent().getXXXExtra方法获取数据,实现数据的传递和共享。
-
启动Service和BroadcastReceiver:Intent不仅可以用于Activity之间的跳转,还可以用于启动Service和发送BroadcastReceiver,实现后台服务和广播通信的功能。
-
处理结果:通过startActivityForResult和onActivityResult方法,可以实现Activity之间的结果返回,实现数据的双向传递。
2.2 Fragment3和 Fragment4的实现
(1)因为Fragment3和Fragment4只是实现展示单一的功能展示,所以只需要设置对应的布局xml文件,添加一个textView控件
3.在MianActivity中将4个Fragment绑定在一起
- 初始化视图和Fragment:
- 通过
findViewById
方法获取了四个LinearLayout的引用(layout1
,layout2
,layout3
,layout4
),这些LinearLayout可能是在XML布局文件中定义的,用于作为Fragment的容器或触发Fragment切换的按钮。 - 创建了四个Fragment的实例(
fragment1
,fragment2
,fragment3
,fragment4
),这些Fragment可能是自定义的,用于显示不同的内容或界面。
- 通过
- 设置FragmentManager和事务:
- 通过
getSupportFragmentManager()
方法获取了FragmentManager的实例(manager
),FragmentManager用于管理Fragment的事务,如添加、移除、替换、显示和隐藏等。 - 通过
manager.beginTransaction()
开始了一个Fragment事务(transaction
),事务用于一次性执行多个Fragment操作,并在最后提交(commit
)以应用这些更改。
- 通过
- 初始化Fragment显示:
- 调用了一个名为
intial()
的方法(尽管代码中没有给出这个方法的实现),这个方法可能用于进行一些初始化操作,比如设置默认的Fragment显示状态。 - 调用了一个名为
fragementHide()
的方法(注意这里有一个拼写错误,应该是fragmentHide()
),这个方法可能用于隐藏所有Fragment,尽管代码中没有给出实现。 - 通过
transaction.show(fragment1)
显示了第一个Fragment,并通过transaction.commit()
提交了事务。
- 调用了一个名为
- 设置点击事件监听器:
- 为
layout1
设置了一个点击事件监听器,当layout1
被点击时,会开始一个新的Fragment事务。 - 在点击事件处理中,首先通过
fragementHide()
方法隐藏所有Fragment(注意拼写错误),然后通过transaction.show(fragment1)
显示第一个Fragment,并最后提交事务
- 为
5.点击事件处理方法(onClick方法)
1.这个方法根据点击的LinearLayout的ID来决定显示哪个Fragment
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
Fragment fragment1,fragment2,fragment3,fragment4;
LinearLayout layout1,layout2,layout3,layout4;
FragmentManager manager;
FragmentTransaction transaction;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main);
layout1 = findViewById(R.id.bottom_linearlayout1);
layout2 = findViewById(R.id.bottom_linearlayout2);
layout3 = findViewById(R.id.bottom_linearlayout3);
layout4 = findViewById(R.id.bottom_linearlayout4);
fragment1 = new Fragment1();
fragment2 = new Fragment2();
fragment3 = new Fragment3();
fragment4 = new Fragment4();
manager = getSupportFragmentManager();
transaction = manager.beginTransaction();
intial();
fragementHide();
transaction.show(fragment1);
transaction.commit();
layout1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
transaction = manager.beginTransaction();
fragementHide();
transaction.show(fragment1);
transaction.commit();
}
});
layout2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
transaction = manager.beginTransaction();
fragementHide();
transaction.show(fragment2);
transaction.commit();
}
});
layout3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
transaction = manager.beginTransaction();
fragementHide();
transaction.show(fragment3);
transaction.commit();
}
});
layout4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
transaction = manager.beginTransaction();
fragementHide();
transaction.show(fragment4);
transaction.commit();
}
});
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.Linearlayout), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets;
});
}
private void intial () {
transaction.add(R.id.fragment_layout1, fragment1);
transaction.add(R.id.fragment_layout1, fragment2);
transaction.add(R.id.fragment_layout1, fragment3);
transaction.add(R.id.fragment_layout1, fragment4);
}
void fragementHide() {
transaction.hide(fragment1);
transaction.hide(fragment2);
transaction.hide(fragment3);
transaction.hide(fragment4);
}
@Override
public void onClick (View v){
int id = v.getId();
if (id == R.id.bottom_linearlayout1) {
fragementHide();
showfragement(fragment1);
} else if (id == R.id.bottom_linearlayout2) {
fragementHide();
showfragement(fragment2);
} else if (id == R.id.bottom_linearlayout3) {
fragementHide();
showfragement(fragment3);
} else if (id == R.id.bottom_linearlayout4) {
fragementHide();
showfragement(fragment4);
} else {
// 处理未知或未处理的ID(可选)
// 例如:Log.e("Navigation", "Unknown ID: " + id);
}
}
public void showfragement (Fragment fragement){
transaction=manager.beginTransaction();
fragementHide();
transaction.show(fragement);
transaction.commit();
}
}
4.创建MusicActivity和MyService来实现页面播放音乐
(1)首先需要在res文件下创建raw文件,将mp3文件添加到到该raw文件下
(2)根据绑定式音乐服务的生命周期函数作为代码逻辑
public class MyService extends Service {
MediaPlayer mediaPlayer;
Context context;
@Override
public void onCreate() {
super.onCreate();
context = this; // 在 onCreate() 中初始化 context
Log.d("LS", "MyService onCreate...");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("LS", "onStartCommand...");
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
Log.d("LS", "MyService onBind...");
Mybinder binder = new Mybinder();
return binder;
}
@Override
public void onDestroy() {
Log.d("LS", "onDestroy...");
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release(); // 释放 MediaPlayer 资源
}
super.onDestroy();
}
public class Mybinder extends Binder {
public void todo() {
Log.d("LS", "MyService Mybinder todo...");
if (mediaPlayer == null) {
mediaPlayer = MediaPlayer.create(context, R.raw.music3);
}
mediaPlayer.start();
}
}
}
三.实现过程
图片需要放在drawable文件下
xml文件放在layout文件下,music3放在raw文件下,音乐文件是mp3格式