一. 当前效果实现:

二、功能说明:
首先搭一个微信的壳子,即有四个界面可以互相跳转--聊天,联系人,发现,我的,每次点开相应微信图标都会跳转到相应界面。
在联系人界面做了一个显示联系人的界面,这里用商品图片代替联系人,当点击相应商品图片的时候会显示它的相应信息。
这里还增加了一个背景音乐,即数据的绑定,当进入联系人界面时就会出现背景音乐,当退出联系人界面后音乐停止。
故需要实现的功能:
1.activity之间的跳转
2.连接数据
3.背景音乐的实现
三、功能实现
1.跳转功能
-
四个界面之间的跳转
涉及以下xml文件:

首先设计微信主界面:

这里进行了xml的嵌套,主界面有三个部分,其中最上面的我的微信和最下面的四个图标各自对应layout_botton.xml和layout_top.xml。
layout_botton.xml: layout_top.xml:

将微信界面大致框架做完后,开始做四个个跳转的界面,以下是四个跳转界面的布局




布局页面做完后,就开始编写进行跳转的代码
public class MainActivity_fragment extends AppCompatActivity implements View.OnClickListener {
Fragment fragment1, fragment2, fragment3, fragment4;
LinearLayout layout1, layout2, layout3, layout4;
FragmentManager manager;
FragmentTransaction transaction;
@SuppressLint("WrongViewCast")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main_fragment);
layout1 = findViewById(R.id.bottom_layout1);
layout2 = findViewById(R.id.bottom_layout2);
layout3 = findViewById(R.id.bottom_layout3);
layout4 = findViewById(R.id.bottom_layout4);
fragment1 = new BlankFragment1();
fragment2 = new BlankFragment2();
fragment3 = new BlankFragment3();
fragment4 = new BlankFragment4();
manager = getSupportFragmentManager();
transaction = manager.beginTransaction();
initial();
fragementhide();
transaction.show(fragment1);
transaction.commit();
private void initial() {
transaction.add(R.id.framelayout1, fragment1);
transaction.add(R.id.framelayout1, fragment2);
transaction.add(R.id.framelayout1, fragment3);
transaction.add(R.id.framelayout1, fragment4);
}
void fragementhide() {
transaction.hide(fragment1);
transaction.hide(fragment2);
transaction.hide(fragment3);
transaction.hide(fragment4);
}
private void showfragement(Fragment fragment) {
transaction = manager.beginTransaction();
fragementhide();
transaction.show(fragment);
transaction.commit();
}
@Override
public void onClick(View view) {
if(view.getId() == bottom_layout1)
{fragementhide();showfragement(fragment1);}
else if(view.getId() == bottom_layout2)
{fragementhide();showfragement(fragment2);}
else if(view.getId() == bottom_layout3)
{fragementhide();showfragement(fragment3);}
else if(view.getId() ==bottom_layout4)
{fragementhide();showfragement(fragment4);}
}
}
在MainActivity_fragment里面定义四个bottom,对应四个微信图标,通过showfragement()和fragementhide(),最后用一个if else语句,实现点击相应微信图标可以跳转到对应界面的功能。
-
联系人界面的跳转
这里有一个intent类
intent
Intent(意图)是一种重要的消息传递对象,用于在不同组件(如活动(Activity)、服务(Service)、广播接收器(BroadcastReceiver)等)之间进行通信和交互。
作用
组件通信:Intent 允许应用程序的不同组件(如活动、服务、广播接收器)之间进行通信。通过发送Intent,一个组件可以请求另一个组件执行特定的操作或返回结果。
启动活动:当你需要从一个活动跳转到另一个活动时,可以使用Intent来启动目标活动。这使得应用程序的导航更加灵活和动态。
启动服务:服务是后台运行的组件,通常用于执行长时间运行的操作,如下载文件或播放音乐。通过Intent,你可以启动或绑定到一个服务,并与之交互。
发送广播:广播是一种消息传递机制,允许应用程序向系统或应用程序的其他部分发送消息。Intent 可以用于发送和接收广播,从而实现应用程序之间的通信。
数据传输:Intent 可以携带数据(如字符串、URI、文件等),这使得数据可以在不同的组件之间传递。这对于实现复杂的交互和数据共享非常有用。
隐式Intent:隐式Intent不指定具体的组件,而是通过定义一个操作(action)、数据类型(data)和类别(category)来请求系统执行相应的操作。这使得应用程序可以更灵活地与其他应用程序或系统服务交互。
显式Intent:显式Intent直接指向特定的组件,如某个活动或服务。这使得开发者可以精确控制应用程序的行为和交互。
原文链接:https://blog.youkuaiyun.com/Patrick_yuxuan/article/details/140530905
1:启动组件,当点击rc_imageView时,从本组件跳到了MainActivity_cantact_detail这个组件
Intent intent=new Intent(context,MainActivity_cantact_detail.class);
2:数据传送,把price,config数据放到了intent这个对象里面
intent.putExtra("price",str1);
intent.putExtra("config",str2);
最后从Adapter.java跳转至MainActivity_cantact_detail.java
2.数据的连接
-
创建列表
需要先用到recycleview控件创建列表
recycleview
RecyclerView是Android中用于展示大量数据列表的高级视图组件。它是对ListView的改进和扩展,提供了更灵活、高效的方式来展示和管理大型数据集。如下图所示:

设计 layout_item.xml

-
存储数据
往列表里面传入数据,先要创建数据源,在 BlankFragment2.java里创建list1列表进行数据存储
List<Map<String,Object>> list1;
list1 =new ArrayList<Map<String,Object>>();
创建一个列表,列表的内容为键值对 键的内容为string ,值的内容为任意类型
每一个map对象都是一个商品,里面存储着它的信息存储的数据如下
String[] price={"1000","2000","3000"};
String[] config={"sss","qqq","rrr"};
通过for循环存入数据
for(int i=0;i<phonename.length;i++)
{
Map<String,Object> map=new HashMap<>();
map.put("name",phonename[i]);
map.put("price",price[i]);
map.put("config",config[i]);
list1.add(map);
}
数据传入之后进行连接,把数据导入进列表
需要用到adapter
-
绑定数据
adapter
是数据源和视图之间的桥梁,把数据绑定到item里
里面有一个叫Holder的类,和一个onBindViewHolder的方法
Holder
在Adapter中,holder用于绑定视图
static class MyViewHolder extends RecyclerView.ViewHolder{
TextView textView1,textView2,textView3;
ImageView imageView;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
imageView=itemView.findViewById(R.id.rc_imageView);
textView2 =itemView.findViewById(R.id.rc_textview2);
textView3 =itemView.findViewById(R.id.rc_textview3);
}
}
如上:这个holder类绑定了layout_item.xml的控件rc_imageView,rc_textview2,rc_textview3。
onBindViewHolder
这个方法是把数据集中的数据绑定到控件中
public void onBindViewHolder(MyViewHolder myViewHolder, int j) {
myViewHolder.imageView.setImageResource(Integer.parseInt(list.get(j).get("name").toString()));
String str1=list.get(j).get("price").toString();
String str2=list.get(j).get("config").toString();
myViewHolder.textView2.setText(str1);
myViewHolder.textView3.setText(str2);
myViewHolder.imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent(context,MainActivity_cantact_detail.class);
intent.putExtra("price",str1);
intent.putExtra("config",str2);
context.startActivity(intent);
}
});
}
这个是数据集的数据
绑定数据集的数据

最终显示页面如下:

3.背景音乐的实现
这里利用绑定式服务启动音乐播放与停止
首先在raw中添加music.mp3

这里要用到binder
binder
绑定式服务的基础知识
→他是Service的子类,开发者要覆写onBind()方法,这个方法返回一个IBinder对象,这个对象里面定义一个公有方法,与服务绑定的组件通过该方法与服务进行通信。
→客户端(客户端就是想要与服务相绑定的那个组件)通过方法:bindService与服务绑定。
→一个服务可以在同一个时间与多个客户端绑定,系统会向每一个与服务绑定的客户端传第一个:IBinder对象,但是,只有第一个与服务想绑定的客户端的”IBinder”对象是通过onBind方法返回的,其他与服务绑定的客户端的”IBinder”对象不是通过onBind方法返回。即onbind()方法只会调用一次。
→当最后一个与服务相绑定的客户端也解绑定了,系统将会销毁服务。
http://原文链接:https://blog.youkuaiyun.com/u010707039/article/details/46473713

通过上图我们可以知道,绑定式服务首先通过onCreate()创建,然后通过onBind()进行绑定,服务结束通过onUnbind()解绑,最后通过onDestroy()进行销毁。
以下是MyService中的关于音乐播放的函数
public class MyService extends Service {
MediaPlayer mediaPlayer;
public MyService() {
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
mediaPlayer=MediaPlayer.create(this,R.raw.music);
mediaPlayer.start();
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
Log.d("yy","MYservice onbind....");
Mybinder binder=new Mybinder();
return binder;
}
@Override
public void onDestroy() {
Log.d("yy","MYservice destroy....");
mediaPlayer.stop();
super.onDestroy();
}
public class Mybinder extends Binder{
public Mybinder() {
}
public void todo()
{
Log.d("yy","MYservice todo....");
mediaPlayer=MediaPlayer.create(getApplicationContext(),R.raw.music);
mediaPlayer.start();
}
}
}
这里我们覆写onBind()方法,返回一个binder对象,binder对象里面的todo方法就是进行音乐的绑定播放
Intent intent=new Intent(this,MyService.class);
ServiceConnection connection=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.d("yy","onserviceconnect....");
mybinder=(MyService.Mybinder) iBinder;
mybinder.todo();
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.d("yy","onservicedisconnect....");
mybinder=null;
}
};
this.bindService(intent,connection, Context.BIND_AUTO_CREATE);
在MainActivity_cantact_detail中我们通过 onServiceConnected()和onServiceDisconnected()进行服务的连接与断开,这边音乐播放不好显示,我添加了Log以便于在logcat中观察音乐绑定过程中函数的调用。如下:

音乐首先onbind()进行绑定,然后连接,todo播放完后退出就被destroy销毁掉。
四、总结
代码编写时也遇到许多难题,如布局界面的设置,代码报错如何看报错行。
这里补充一点,里面各种图片的显示如微信图标和商品图片,要先在网上找到合适图片重命名成png的形式,然后放入drawable目录下

如果是在xml文件中直接替换图片,找到srcCompat进行修改即可,然后代码前面的tools要改成app图片才会在虚拟机中显示

如果是在一个xml中进行传入,如上面联系人界面,布局是 layout_item.xml,但实际显示却有三张图片,则需要编写代码进行传入。
int[] phonename={R.drawable.p1,R.drawable.p2,R.drawable.p3};
for(int i=0;i<phonename.length;i++)
{
Map<String,Object> map=new HashMap<>();
map.put("name",phonename[i]);
list1.add(map);
}
如代码所示,先将图片放进列表中,在用for循环将值传入map中。
以上是微信界面开发的基本布局,后续还会再里面添加其他的功能和部件,持续更新...
139

被折叠的 条评论
为什么被折叠?



