美文网首页
ShoppingMallApp01

ShoppingMallApp01

作者: GeekGray | 来源:发表于2018-10-03 19:30 被阅读13次

阅读原文

框架搭建

1.软件分包

com.example.shoppingmall

app

base

community

home

shoppingcart

type

user

utils

view

2. 启动页面布局文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:id="@+id/activity_main"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="#ffffff">


    <ImageView
        android:id="@+id/app_logo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerInParent="true"
        android:src="@drawable/shoppingapp_logo" />


</RelativeLayout>

3. 启动页面代码

    public class SplashActivity extends Activity
    {
    private static final String TAG = SplashActivity.class.getSimpleName();//"SplashActivity"
    private boolean isStartMain = false;//是否进入主界面标志
    private Handler handler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash);

        handler.postDelayed(new Runnable()
        {
            @Override
            public void run()
            {
                //两秒后才执行到这里
                //执行在主线程中
                startActivity(new Intent(SplashActivity.this, MainActivity.class));
                finish();
            }
        }, 2000);
    }


    /**
     * 跳转到主页面,并且把当前页面关闭掉
     */
    private void startMainActivity()
    {
        if (!isStartMain)
        {
            isStartMain = true;
            Intent intent = new Intent(this, MainActivity.class);
            startActivity(intent);
            //关闭当前页面
            finish();
        }

    }

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        Log.e(TAG, "onTouchEvent==Action" + event.getAction());
        startMainActivity();
        return super.onTouchEvent(event);
    }

    @Override
    protected void onDestroy()
    {
        //把所有的消息和回调移除
        handler.removeCallbacksAndMessages(null);
        super.onDestroy();
    }
}

主页面

1. 主页面布局文件

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

    <FrameLayout
        android:id="@+id/frameLayout"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />


    <RadioGroup
        android:id="@+id/rg_main"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:background="@drawable/home_bottom_parent_bg"
        android:orientation="horizontal">

        <RadioButton
            android:id="@+id/rb_home"
            style="@style/MainButtonStyle"
            android:drawableTop="@drawable/home_button_selector"
            android:text="首页" />

        <RadioButton
            android:id="@+id/rb_type"
            style="@style/MainButtonStyle"
            android:drawableTop="@drawable/type_button_selector"
            android:text="分类" />

        <RadioButton
            android:id="@+id/rb_community"
            style="@style/MainButtonStyle"
            android:drawableTop="@drawable/community_button_selector"
            android:paddingTop="10dp"
            android:text="发现" />

        <RadioButton
            android:id="@+id/rb_cart"
            style="@style/MainButtonStyle"
            android:drawableTop="@drawable/cart_button_selector"
            android:text="购物车" />

        <RadioButton
            android:id="@+id/rb_user"
            style="@style/MainButtonStyle"
            android:drawableTop="@drawable/user_button_selector"
            android:text="个人中心" />
    </RadioGroup>


</LinearLayout>

2. 按钮样式

<style name="MainButtonStyle">
        <!-- Customize your theme here. -->
        <item name="android:layout_width">0dp</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:layout_weight">1</item>
        <item name="android:button">@null</item>
        <item name="android:textColor">@drawable/bottom_button_text_selector</item>
        <item name="android:textSize">10sp</item>
        <item name="android:gravity">center</item>
    </style>

3. 使用 Butterknife 初始化布局

1. 配置快捷键

(1) 在 Setting->Plugins 中输入 butterknife 添加插件
(2) Android ButterKnife Aelezny ->点击安装

2. Module 里的 build.gradle(app) 里面添加

compile 'com.jakewharton:butterknife:7.0.1'

3. 在 MainActivity 中使用

    public class MainActivity extends FragmentActivity 
    {
            @Bind(R.id.frameLayout)
            FrameLayout frameLayout;
            @Bind(R.id.rb_home)
            RadioButton rbHome;
            @Bind(R.id.rb_type)
            RadioButton rbType;
            @Bind(R.id.rb_community)
            RadioButton rbCommunity;
            @Bind(R.id.rb_cart)
            RadioButton rbCart;
            @Bind(R.id.rb_user)
            RadioButton rbUser;
            @Bind(R.id.rg_main)
            RadioGroup rgMain;
            @Override
            protected void onCreate(Bundle savedInstanceState) 
            {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            //Butternif 和 Activity 绑定
            ButterKnife.bind(this);
        }
    }

Fragment 的基类和各个子 Fragment

BaseFragment

/**
 * @author: Hashub
 * @WeChat: NGSHMVP
 * @Date: 2018/8/24 16:53
 * @function:基类Fragemnt
 * 首页:HomeFragment
 * 分类:UserFragment
 * 发现:CommunityFragment
 * 购物车:ShoppingCartFragment
 * 用户中心:UserFragemnt
 * 等都要继承该类
 */
public abstract class BaseFragment extends Fragment
{
    protected Context mContext;

    /**
     * 当该类被系统创建的时候被回调
     *
     * @param savedInstanceState
     */
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        mContext=getActivity();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
    {
        return initView();
    }

    /**
     * 抽象类,由孩子实现,实现不同的效果
     * @return
     */
    public abstract View initView() ;

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState)
    {
        super.onActivityCreated(savedInstanceState);
        initData();
    }

    /**
     * 当子类需要联网请求数据的时候,可以重写该方法,在该方法中联网请求
     */
    public  void initData()
    {

    }

}

各个子 Fragment 创建

首页: HomeFragment

分类: TypeFragment

发现: CommunityFragment

购物车: ShoppingCartFragment

用户中心: UserFragemnt

以HomeFragment页面的内容为例如下

/**
 * @author: Hashub
 * @WeChat: NGSHMVP
 * @Date: 2018/8/24 16:53
 * @function:
 */
public class HomeFragment extends BaseFragment
{

    @Override
    public View initView()
    {
        return null;
    }
}

初始化各个 Fragment 并且切换

1. 初始化各个 Fragment

    /**
     * 初始化Fragment
     * 添加的时候要按照顺序
     */
    private void initFragment()
    {
        fragments = new ArrayList<>();
        fragments.add(new HomeFragment());
        fragments.add(new TypeFragment());
        fragments.add(new CommunityFragment());
        fragments.add(new ShoppingCartFragment());
        fragments.add(new UserFragment());
    }

2. 各个 Fragment 的切换

    /**
     * 设置RadioGroup的监听
     */
    private void initListener()
    {
        rgMain.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener()
        {

            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId)
            {
                switch (checkedId)
                {
                    case R.id.rb_home://主页
                        position = 0;
                        break;
                    case R.id.rb_type://分类
                        position = 1;
                        break;
                    case R.id.rb_community://发现
                        position = 2;
                        break;
                    case R.id.rb_cart://购物车
                        position = 3;
                        break;
                    case R.id.rb_user://用户中心
                        position = 4;
                        break;
                    default:
                        position = 0;
                        break;
                }
                //根据位置取不同的Fragment
                BaseFragment baseFragment = getFragment(position);
                /**
                 * 第一参数:上次显示的Fragment
                 * 第二参数:当前正要显示的Fragment
                 */
                switchFragment(tempFragemnt, baseFragment);
            }
        });
    }

    /**
     * 切换Fragment
     *
     * @param fromFragment
     * @param nextFragment
     */
    private void switchFragment(Fragment fromFragment, BaseFragment nextFragment)
    {
        if (tempFragemnt != nextFragment)
        {
            tempFragemnt = nextFragment;
            if (nextFragment != null)
            {
                FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
                //判断nextFragment是否添加
                if (!nextFragment.isAdded())
                {
                    //隐藏当前Fragment
                    if (fromFragment != null)
                    {
                        transaction.hide(fromFragment);
                    }
                    //添加Fragment
                    transaction.add(R.id.frameLayout, nextFragment).commit();
                }
                else
                {
                    //隐藏当前Fragment
                    if (fromFragment != null)
                    {
                        transaction.hide(fromFragment);
                    }
                    transaction.show(nextFragment).commit();
                }
            }
        }
    }

    /**
     * 根据位置取不同的Fragment
     *
     * @param position
     * @return
     */
    private BaseFragment getFragment(int position)
    {
        if (fragments != null && fragments.size() > 0)
        {
            BaseFragment baseFragment = fragments.get(position);
            return baseFragment;
        }
        return null;
    }

主页面结构分析

主页面实现分析

布局,最外层是相对布局:顶部是线性布局,里面两个 TextView;

中间是使用分类型的 RecyclerView
当滑动底部的时候显示跳转到顶部的按钮;

注意,实现该布局最好是相对布局和帧布局。

主页面布局实现 fragment_home.xml

首页布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".home.fragment.HomeFragment">

    <include
        android:id="@+id/titlebar"
        layout="@layout/titlebar" />

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv_home"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/titlebar" />

    <ImageButton
        android:id="@+id/ib_top"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_marginBottom="20dp"
        android:layout_marginRight="20dp"
        android:background="@drawable/top_btn"
        android:visibility="gone" />
</RelativeLayout>

标题栏

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

    <TextView
        android:id="@+id/tv_search_home"
        android:layout_width="wrap_content"
        android:layout_height="35dp"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="10dp"
        android:layout_weight="1"
        android:background="@drawable/search_home_shape"
        android:drawableLeft="@drawable/home_search_icon"
        android:drawablePadding="10dp"
        android:gravity="center_vertical"
        android:padding="5dp"
        android:text="输入搜索信息"
        android:textSize="13sp" />

    <TextView
        android:id="@+id/tv_message_home"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:drawableTop="@drawable/new_message_icon"
        android:text="消息"
        android:textColor="#fff" />
</LinearLayout>

RecyclerView 使用

//注意:版本号根据具体编译环境更改
compile 'com.android.support:recyclerview-v7:23.3.0'

初始化布局和设置监听

/**
 * @author: Hashub
 * @WeChat: NGSHMVP
 * @Date: 2018/8/24 16:53
 * @function:
 */
public class HomeFragment extends BaseFragment
{

    private static final String TAG = HomeFragment.class.getSimpleName();

    private RecyclerView rvHome;
    private ImageView ib_top;
    private TextView tv_search_home;
    private TextView tv_message_home;
    private HomeFragmentAdapter adapter;
    private ResultBeanData.ResultBean resultBean;//返回的数据

    @Override
    public View initView()
    {
        Log.e(TAG, "主页的Fragment的UI被初始化了");
        View view = View.inflate(mContext, R.layout.fragment_home, null);
        rvHome = (RecyclerView) view.findViewById(R.id.rv_home);
        ib_top = (ImageView) view.findViewById(R.id.ib_top);
        tv_search_home = (TextView) view.findViewById(R.id.tv_search_home);
        tv_message_home = (TextView) view.findViewById(R.id.tv_message_home);

        //设置点击事件
        initListener();
        return view;
    }

    @Override
    public void initData()
    {
        super.initData();
        Log.e(TAG, "主页的Fragment的数据被初始化了");
        //联网请求主页的数据
        getDataFromNet();

    }

    /**
     * 联网请求主页的数据
     */
    private void getDataFromNet()
    {
        String homeUrl = Constants.HOME_URL;
        OkHttpUtils
                .get()
                .url(homeUrl)
                .build()
                .execute(new StringCallback()
                {
                    /**
                     * 当请求失败的时候回调
                     * @param call
                     * @param e
                     * @param id
                     */
                    @Override
                    public void onError(Call call, Exception e, int id)
                    {
                        Log.e(TAG,"首页请求失败=="+e.getMessage());
                    }

                    /**
                     * 当联网成功的时候回调
                     * @param response 请求成功的数据
                     * @param id
                     */
                    @Override
                    public void onResponse(String response, int id)
                    {
                        Log.e(TAG,"首页请求成功=="+response);
                        //解析数据
                        processData(response);
                    }
                });

    }

    /**
     * 解析数据
     * @param json
     */
    private void processData(String json)
    {
        ResultBeanData resultBeanData = JSON.parseObject(json, ResultBeanData.class);
        resultBean=resultBeanData.getResult();
        if(resultBean!=null)
        {
            //有数据
            //设置适配器
            adapter=new HomeFragmentAdapter(mContext,resultBean);
            rvHome.setAdapter(adapter);
            GridLayoutManager manager=new GridLayoutManager(mContext,1);
            //设置跨度大小监听
            manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup()
            {
                @Override
                public int getSpanSize(int position)
                {
                    if(position<=3)
                    {
                        //隐藏
                        ib_top.setVisibility(View.GONE);
                    }
                    else
                    {
                        //显示
                        ib_top.setVisibility(View.VISIBLE);
                    }
                    //只能返回1
                    return 1;
                }
            });
            //设置布局管理者
            rvHome.setLayoutManager(manager);
        }
        else
        {
            //没有数据
        }
        Log.e(TAG,"解析成功=="+resultBean.getHot_info().get(0).getName());
    }


    /**
     * 设置点击事件
     */
    private void initListener()
    {
        //置顶的监听
        ib_top.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                //回到顶部
                rvHome.scrollToPosition(0);
            }
        });

        //搜素的监听
        tv_search_home.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                Toast.makeText(mContext, "搜索", Toast.LENGTH_SHORT).show();
            }
        });

        //消息的监听
        tv_message_home.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                Toast.makeText(mContext, "进入消息中心", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

请求主页数据和解决数据

使用 OkHttpUtils 请求网络

下载地址:

https://github.com/hongyangAndroid/okhttputils

在 build.gradle(app) 配置如下:

compile 'com.zhy:okhttputils:2.6.2'

在 build.gradle(project)配置如下:

allprojects {
    repositories {
        jcenter()
        maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
    }
}

配置联网路径

/**
 * @author: Hashub
 * @WeChat: NGSHMVP
 * @Date: 2018/8/26 9:10
 * @function:配置各个页面联网地址
 */
public class Constants
{

    //    public static String BASE_URL = "http://192.168.51.104:8080/atguigu";
    public static String BASE_URL = "http://192.168.1.102:80/atguigu";

    /**
     * 主页面的路径
     */
    public static String HOME_URL = BASE_URL + "/json/HOME_URL.json";
    /**
     * 图片的基本路径
     */
    public static String BASE_URL_IMAGE = BASE_URL + "/img";


}

使用 fastjson 解析数据

下载地址:

https://github.com/alibaba/fastjson

先添加 fastjson 的 jar 包,再配置本机ip及Tomcat服务器的端口号

//主页的路径
http://10.0.2.2:80/atguigu/json/HOME_URL.json

生成 JeanBean

使用 GsonFromat 生成 ResultBeanData 对象

主页面适配器

适配器 6 种类型

/**
 * @author: Hashub
 * @WeChat: NGSHMVP
 * @Date: 2018/8/26 9:00
 * @function:
 */
public class HomeFragmentAdapter extends RecyclerView.Adapter
{

    /**
     * 广告条幅类型
     */
    public static final int BANNER = 0;

    /**
     * 频道类型
     */
    public static final int CHANNEL = 1;
    /**
     * 活动类型
     */
    public static final int ACT = 2;
    /**
     * 秒杀类型
     */
    public static final int SECKILL = 3;
    /**
     * 推荐类型
     */
    public static final int RECOMMEND = 4;
    /**
     * 热卖
     */
    public static final int HOT = 5;
    private static final String GOODS_BEAN = "goodsBean";
    /**
     * 用来初始化布局
     */
    private LayoutInflater mLayoutInflater;
    private Context mContext;
    /**
     * 数据
     */
    private ResultBeanData.ResultBean resultBean;

    /**
     * 当前类型
     */
    private int currentType = BANNER;

构造方法传入参数&getItemCount 和 getItemViewType

public HomeFragmentAdapter(Context mContext, ResultBeanData.ResultBean resultBean)
    {
        this.mContext = mContext;
        this.resultBean = resultBean;
        mLayoutInflater = LayoutInflater.from(mContext);
    }

 /**
     * 得到类型
     *
     * @param position
     * @return
     */
    @Override
    public int getItemViewType(int position)
    {
        switch (position)
        {
            case BANNER:
                currentType = BANNER;
                break;
            case CHANNEL:
                currentType = CHANNEL;
                break;
            case ACT:
                currentType = ACT;
                break;
            case SECKILL:
                currentType = SECKILL;
                break;
            case RECOMMEND:
                currentType = RECOMMEND;
                break;
            case HOT:
                currentType = HOT;
                break;
        }
        return currentType;
    }

    @Override
    public int getItemCount()
    {
        //开发过程中从1-->6
        return 6;
    }

相关文章

  • ShoppingMallApp01

    阅读原文 框架搭建 1.软件分包 com.example.shoppingmallappbasecommunity...

网友评论

      本文标题:ShoppingMallApp01

      本文链接:https://www.haomeiwen.com/subject/qbctaftx.html