Android 开发--微信界面开发

一. 当前效果实现:

二、功能说明:

首先搭一个微信的壳子,即有四个界面可以互相跳转--聊天,联系人,发现,我的,每次点开相应微信图标都会跳转到相应界面。

在联系人界面做了一个显示联系人的界面,这里用商品图片代替联系人,当点击相应商品图片的时候会显示它的相应信息。

这里还增加了一个背景音乐,即数据的绑定,当进入联系人界面时就会出现背景音乐,当退出联系人界面后音乐停止。

故需要实现的功能:

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中。

以上是微信界面开发的基本布局,后续还会再里面添加其他的功能和部件,持续更新...

源码地址

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值