Android 开发—Lemon檬你不行

一.实现效果图

这是一个柠檬购买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绑定在一起

  1. 初始化视图和Fragment
    • 通过findViewById方法获取了四个LinearLayout的引用(layout1, layout2, layout3, layout4),这些LinearLayout可能是在XML布局文件中定义的,用于作为Fragment的容器或触发Fragment切换的按钮。
    • 创建了四个Fragment的实例(fragment1, fragment2, fragment3, fragment4),这些Fragment可能是自定义的,用于显示不同的内容或界面。
  2. 设置FragmentManager和事务
    • 通过getSupportFragmentManager()方法获取了FragmentManager的实例(manager),FragmentManager用于管理Fragment的事务,如添加、移除、替换、显示和隐藏等。
    • 通过manager.beginTransaction()开始了一个Fragment事务(transaction),事务用于一次性执行多个Fragment操作,并在最后提交(commit)以应用这些更改。
  3. 初始化Fragment显示
    • 调用了一个名为intial()的方法(尽管代码中没有给出这个方法的实现),这个方法可能用于进行一些初始化操作,比如设置默认的Fragment显示状态。
    • 调用了一个名为fragementHide()的方法(注意这里有一个拼写错误,应该是fragmentHide()),这个方法可能用于隐藏所有Fragment,尽管代码中没有给出实现。
    • 通过transaction.show(fragment1)显示了第一个Fragment,并通过transaction.commit()提交了事务。
  4. 设置点击事件监听器
    • 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格式

源码地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值