android studio实验五 搭建主页框架

一、实验目的
掌握各类代码的分类管理知识,掌握移动电商项目主页架构搭建, 掌握Fragment的使用。掌握菜单页内容切换以及菜单样式切换的开发技术。
二、实验设备及器件
Android Studio
三、实验内容
1.创建一个Android应用,设置项目名MobileShop,包名为com.huatec.edu.mobileshop,创建activity包存放Activity,创建fragment存放Fragment。
2.创建drawable-xhdpi目录,解压图片资源包xhdpi.rar里的所有文件到该目录下。
3.在fragment下创建HomeFragment,CategoryFragment,CartFragment,PersonFragment分别对应首页,分类,购物车,我的(个人中心)页面。
4、在fragment下创建NavigationFragment作为主页最外层内容,上半部分切换各页面Fragment下半部分是导航栏,点击切换Fragment。
5、修改MainActivity内容,将NavigationFragment添加到窗口显示。

最终效果:在这里插入图片描述在这里插入图片描述
代码结构:
在这里插入图片描述
资源结构:
在这里插入图片描述
四、实验步骤
1、创建一个项目,项目名称:MobileShop 项目包名:com.huatec.edu.mobileshop
然后加入项目需要的各种包:
在这里插入图片描述
2、创建drawable-xhdpi目录,解压图片资源包xhdpi.rar里的所有文件到该目录下。
在这里插入图片描述
3、在NavigationFragment添加一个导航栏,添加四个按钮,在点击不同按钮时切换到对应的页面,所以我们先创建四个Fragment。
在layout里创建四个布局文件:fragment_home.xml、fragment_category.xml、fragment_cart.xml、fragment_person.xml。在com.huatec.edu.mobileshop.fragment包下创建4个Fragment类:HomeFragment,CategoryFragment,CartFragment,PersonFragment。代码如下:
fragment_home.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!--首页测试页面-->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="首页"
        android:textSize="20sp"/>
</LinearLayout>

HomeFragment:

package com.example.administrator.myapplication.fragment;

import android.os.Bundle;
import android.app.Fragment;
import android.support.v4.view.LayoutInflaterCompat;
import android.support.v7.app.AppCompatActivity;
import android.text.Layout;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.example.administrator.myapplication.R;

/**
 * Created by Administrator on 2020/5/24 0024.
 */

    //fragment在教程P.139
    //ViewGroup在教程39

public class HomeFragment extends Fragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState){
        //用于创建和返回跟fragment关联的View对象
        View view = inflater.inflate(R.layout.fragment_home,container,false);
//      LayoutInflater inflater:作用类似于findViewById(),
//      findViewById()用来寻找xml布局下的具体的控件(Button、TextView等),
//      LayoutInflater inflater()用来找res/layout/下的xml布局文件
//      ViewGroup container:表示容器,View放在里面
//      Bundle savedInstanceState:保存当前的状态,在活动的生命周期中,
//                  只要离开了可见阶段,活动很可能就会被进程终止,这种机制能保存当时的状态
        return view;
    }
}

fragment_category.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!--分类测试页面-->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="分类"
        android:textSize="20sp"/>
</LinearLayout>

CategoryFragment:

package com.example.administrator.myapplication.fragment;

import android.os.Bundle;
import android.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.example.administrator.myapplication.R;

/**
 * 分类fragment
 */

public class CategoryFragment extends Fragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState){
        View view = inflater.inflate(R.layout.fragment_category,container,false);
        return view;
    }
}

fragment_cart.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!--购物车测试页面 -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="购物车"
        android:textSize="20sp"/>
</RelativeLayout>

CartFragment:

package com.example.administrator.myapplication.fragment;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.example.administrator.myapplication.R;

/**
 * 购物车fragment
 */

public class CartFragment extends Fragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle saveInstenceState){
        View view = inflater.inflate(R.layout.fragment_cart,null);
        //inflate(int resource,ViewGroup root,boolean attachToRoot)

        //resource:布局资源id

        //root:resource生成view对象要填入的父布局。
        // 为null,则返回的view就是布局资源;否则,需要参照第三个参数

        //attachToRoot:是否将resource生成view对象填入root,以root作为最终返回view的根布局。
        // false,root不为null,则提供root的LayoutParams约束resource生成的view;
        // true,root不为null,以root作为最终返回view的根布局

        //inflate(int resource,ViewGroup root)

        //resource:布局资源

        //root:resource生成view对象要填入的父布局。
        // 为null,则返回的view就是布局资源的根布局;
        // 否则,返回的view以传入的root为根布局(相当于上面的那个第三个参数为true)

        return view;
    }
}

fragment_person.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!--个人中心测试-->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="个人中心"
        android:textSize="20sp"/>
</RelativeLayout>

PersonnalFragment:

package com.example.administrator.myapplication.fragment;

import android.os.Bundle;
import android.os.ParcelUuid;
import android.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.example.administrator.myapplication.R;

/**
 * 个人中心fragment
 */

public class PersonFragment extends Fragment {
    public View onCreateView(final LayoutInflater inflater, ViewGroup container,
                             Bundle saveInstanceState){
        View view = inflater.inflate(R.layout.fragment_person,container,false);
        return view;
    }
}

创建完四个Fragment之后把他们添加到NavigationFragment的上半部,下半部分添加一个导航栏,以下是NavigationFragment对应的代码:

fragment_navigation.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!--不显示Fragment的内容窗口-->
    <FrameLayout
        android:id="@+id/fl_main_navigation"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"></FrameLayout>

    <!--底部菜单栏-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:orientation="horizontal"
        android:layout_weight="0">

    <!--首页菜单-->
    <ImageButton
        android:id="@+id/ib_home"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:background="@android:color/black"
        android:src="@drawable/tab_item_home_normal"/>

        <!--分类菜单-->
        <ImageButton
            android:id="@+id/ib_category"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@android:color/black"
            android:src="@drawable/tab_item_category_normal"/>

        <!--购物车菜单-->
        <ImageButton
            android:id="@+id/ib_cart"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@android:color/black"
            android:src="@drawable/tab_item_cart_normal"/>

        <!--个人中心菜单-->
        <ImageButton
            android:id="@+id/ib_personal"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@android:color/black"
            android:src="@drawable/tab_item_personal_normal"/>
    </LinearLayout>
</LinearLayout>

NavigationFragment类代码:

package com.example.administrator.myapplication.fragment;

import android.app.Fragment;
//import:导入,引入
//导入的包必须一样的,新建了5个fragment,5个导入的包都要用这个

import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;

import com.example.administrator.myapplication.R;

/**
 * 导航fragment,包括内容区和下面的菜单栏
 */

public class NavigationFragment extends Fragment implements  View.OnClickListener{
//    底部上的四个图片按钮
    private ImageButton mIbHome;
    private ImageButton mIbCategory;
    private ImageButton mIbCart;
    private ImageButton mIbPersonal;
//    定义几个控件的名字,私有的

//    窗口显示的四个Fragment
    private HomeFragment homeFragment;
    private CategoryFragment categoryFragment;
    private CartFragment cartFragment;
    private PersonFragment personFragment;

    public  NavigationFragment() {
    }

    public View onCreateView(LayoutInflater inflater,ViewGroup container,
                             Bundle saveInstanceState){
        View view = inflater.inflate(R.layout.fragment_navigation,container,false);
//        inflate()的作用就是将一个用xml定义的布局文件查找出来,
//        注意与findViewById()的区别,inflate是加载一个布局文件,
//        而findViewById则是从布局文件中查找一个控件。
        //第三个参数为true那么返回可能就不是view。当为fale的时候返回就是View。
        //inflate(int resource,ViewGroup root,boolean attachToRoot)

        //resource:布局资源id

        //root:resource生成view对象要填入的父布局。
        //      为null,则返回的view就是布局资源;否则,需要参照第三个参数

        //attachToRoot:是否将resource生成view对象填入root,以root作为最终返回view的根布局。
        //      false,root不为null,则提供root的LayoutParams约束(限制)resource生成的view;
        //      true,root不为null,以root作为最终返回view的根布局

        //inflate(int resource,ViewGroup root)

        //resource:布局资源

        //root:resource生成view对象要填入的父布局。
        //      为null,则返回的view就是布局资源的根布局;
        //      否则,返回的view以传入的root为根布局(相当于上面的那个第三个参数为true)




        initView(view);//天字第一号进程
        //初始化就是把变量赋为默认值,把控件设为默认状态,把没准备的准备好。
        // 把该给我的分给我。布局文件和一些资源需要在代码里面知初始化声明,
        // 才能使用某些方法进行相关操作。简单点儿说,就道是你想加载页面,
        // 必须先要告诉我页面里面都有什么,然后你才能调用界面里控件的方法和属性,
        // 你不属初始化不告诉我,就找不到相关资源,就无法使用相关的方法。
        //初始化所有控件,第一种是全局的,比如你oncreate里初始化了,onresume里也可以用;
        //第二copy种是局部变量,
        // 比如你在Oncreate里初始化了,
        // 只能在Oncreate里用,到onresume里就不能使用了。
        return view;
    }   //这个意思就是返回要浏览的视图(也就是我们的页面文件)他的名字是与你的控制器名字一样的view
        //这里就是初始化完以后就返回视图 前面View view中的view;这个view是已经加了f_n的界面

    //
    //初始化fragment里所有的控件
    //
    protected void initView(View view){

        //获取菜单图片按钮实例对象
        mIbHome = view.findViewById(R.id.ib_home);
        //findViewById的返回值必须(默认)为View类型,(xx)findViewById(R.XX.XX)前面xx是强制转换类型;
        //view.findViewById(R.id.ib_home);view就是前面指定的View类有一个具体的方法就是调用 findViewById,并且传入一个资源 id,
        // findViewById 方法会找到与传入的 id 相对应的 View,
        // Activity 在 XML 的视图层次结构中搜索这个视图,再在 onCreate 方法中处理它,
        // 这个 activity 的 onCreate 方法建立了一个视图层次结构。然后 findViewById 方法遍历它,找到那个视图层次结构中的某个 View,这个方法的返回值是 View 类型的对象。

        mIbCategory = view.findViewById(R.id.ib_category);
        mIbCart = view.findViewById(R.id.ib_cart);
        mIbPersonal = view.findViewById(R.id.ib_personal);

        //图片按钮设置监听器,因为本类已实现View.onClickListener,
        // 所以可以使用本类做按钮监听,就是点击按钮才会运行的
        mIbHome.setOnClickListener(this);
        mIbCategory.setOnClickListener(this);
        mIbCart.setOnClickListener(this);
        mIbPersonal.setOnClickListener(this);

        //初始化所有控件后,默认选中并显示内容
        select(mIbHome);
    }

    private void select(View v) {
        //重置UI,将按钮菜单全部恢复为未选中的状态
       /* Android 获取设置好的image.setImageResource(R.drawable.xxx)资源

                第一步设置资源
        image.setImageResource(R.drawable.xxx);
        image.setTag(R.drawable.xxx);
        第二步获取资源
        int res = (int) image.getTag();
        第三步做一些判断
        if(res==R.drawable.xxa){
……..
        }else if(res==R.drawable.xxb){
…….
        }*/
        mIbHome.setImageResource(R.drawable.tab_item_home_normal);
        mIbCategory.setImageResource(R.drawable.tab_item_category_normal);
        mIbCart.setImageResource(R.drawable.tab_item_cart_normal);
        mIbPersonal.setImageResource(R.drawable.tab_item_personal_normal);

        //启动fragment事务管理fragment
        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
//        FragmentTransaction 的创建:
//        FragmentTransaction是用来换页面的,
//        ed:想从微信的消息页面换到通讯录的页面就要用这个才行。

        //隐藏所有Fragment
        if (homeFragment != null) {
            fragmentTransaction.hide(homeFragment);
            //hide(Fragement fragment)
//            hide(Fragment fragment): hide	隐藏容器中的 Fragment
//            隐藏已经存在的fragment,
//            只适用那些视图已经被添加到容器中的Fragment,
//            hide 和 show 是配对的,当要显示隐藏的 Fragment A 时,就 show(A);
//            而对于其他 Fragment,则先 hide 起来,等之后要显示时再 show
//            fragmentTransaction.hide(homeFragment);
//                 事物管理,隐藏(显示),(叫xx);
//              如果可找到homeFragment,不为空,
//              打开的是这个页面,就把它藏起来。
//              ed:微信消息页面换到通讯录页面要把消息页面隐藏起来。
        }
        if (cartFragment != null) {
            fragmentTransaction.hide(cartFragment);
            //不为空代表已经有实例了  不需要new
        }
        if (categoryFragment != null) {
            fragmentTransaction.hide(categoryFragment);
        }
        if (personFragment != null) {
            fragmentTransaction.hide(personFragment);
        }

//        根据选中的菜单按钮的id来执行不同的操作
        switch (v.getId()){
//            循环语句switch,获取其资源id,通过资源id,可以判断用户点击了哪个按钮了
 switch语句格式
//            switch(表达式){
//                case 值1:
//                    语句体1;
//                    break;}

            case R.id.ib_home://点击了首页菜单
                mIbHome.setImageResource(R.drawable.tab_item_home_focus);
                //设置菜单图片为这张
                if (homeFragment == null){
                    //如果fragment未初始化,则初始化在加入显示
                    //一个按钮已经点过一次了,按钮已经暗了
                    // 还想再点一次,就要初始化回到没点击之前,之后就可再点了。
                    //不然会出现点了没有用,跟没点一样的情况(不显示),它已经被按下去了,
                    //不恢复一下,就没法再点了
                    homeFragment = new HomeFragment();
                    fragmentTransaction.add(R.id.fl_main_navigation,homeFragment);
                    //addToBackStack()是把被替换的Fragment放入回退栈中
        }
        else{
                    //如果fragment已经初始化,则直接显示,
                    fragmentTransaction.show(homeFragment);
                }
                break;
            case R.id.ib_category:
                mIbCategory.setImageResource(R.drawable.tab_item_category_focus);
                if (categoryFragment == null){
                    //为空代表没有实例  需要new一个
                    categoryFragment = new CategoryFragment();
                    fragmentTransaction.add(R.id.fl_main_navigation,categoryFragment);
                }
                else{
                    fragmentTransaction.show(categoryFragment);
                    //show,hide,remove 格式都是一样的
                }
                break;
            case R.id.ib_cart:
                mIbCart.setImageResource(R.drawable.tab_item_cart_focus);
                if (cartFragment == null){
                    cartFragment = new CartFragment();
                    fragmentTransaction.add(R.id.fl_main_navigation,cartFragment);
                }
                else{
                    fragmentTransaction.show(cartFragment);
                }
                break;
            case R.id.ib_personal:
                mIbPersonal.setImageResource(R.drawable.tab_item_personal_focus);
                if (personFragment == null){
                    personFragment = new PersonFragment();
                    fragmentTransaction.add(R.id.fl_main_navigation,personFragment);
                }
                else{
                    fragmentTransaction.show(personFragment);
                    //show(Fragement fragment)
                }
                break;
        }
        fragmentTransaction.commit();
    }


    @Override
    public void onClick(View v) {
            select(v);
    }
}

4、修改MainActivity内容,将NavigationFragment添加到窗口显示。

activity_main.xml:

<?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"
    tools:context="com.example.administrator.myapplication.acticity.MainActivity">

    <FrameLayout
        android:id="@+id/fl_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></FrameLayout>
</LinearLayout>

MainActivity代码:

package com.example.administrator.myapplication.acticity;

import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import com.example.administrator.myapplication.R;
import com.example.administrator.myapplication.fragment.NavigationFragment;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //调用父类的oncreate方法,完成系统工作,父类指AppCompatActivity(源码里)

        setContentView(R.layout.activity_main);
        //一旦调用 setContentView,activity就会找到 XML 布局文件,并且读取它的每行代码,
        //我们没有创建新的 TextView对象,我们只是在视图树中找到了现有的 TextView,
        // 为了与这个视图树中的 View 进行交互,我们应该创建变量,用来引用这些具体的 View,

        initView();
    }

//    初始化控件
    protected void initView(){
        //开始fragment事务
        //FragmentTransaction 的创建
        FragmentManager fragmentManager = getFragmentManager();
        //getFragmentManager();来获得一个对象赋给fragmentManager;找实例的
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            //                                               //返回(开始一个事务)事务对象

        // FragmentTransaction transaction = getFragmentManager().beginTransaction();

        //将fragment添加到activity_main.xml的fl_main控件上
        fragmentTransaction.replace(R.id.fl_main, new NavigationFragment());
                            //先将之前存在于容器的 Fragment 全部移除(销毁),
                            // 然后添加要显示的 Fragment(会重新执行一遍它的生命流程)
        //显示NavigationFragment,还没有,先new一个 后replace(显示)它
        //xx方法里的 , 功能 , (在哪实现,实现的是什么)
        fragmentTransaction.commit();
        //提交事务
        //FragmentTransaction现在提供了四种不同的方法来commit一个
        // transaction:commit()、
        // commitAllowingStateLoss()、
        // commitNow()、立即执行并且只会执行你当前要提交的transaction。
        // commitNowAllowingStateLoss()。
        // 1.如果你操作很多transactions, 并且不需要同步, 或者你需要把transactions加在back stack里, 那就使用commit().
        // 2.如果你需要同步的操作, 并且你不需要加到back stack里, 使用commitNow().
        // 3.当报错“IllegalStateException:Can not perform this action after onSaveInstanceState”时,使用commitAllowingStateLoss()。
        // 4.如果你希望在某一个指定的点, 确保所有的transactions都被执行, 那么使用executePendingTransactions().
    }
}

结果:
在这里插入图片描述
篮奏云apk地址:
https://rod.lanzous.com/b0dk28ida
密码:6k50

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值