关于NewHomeFragment商城首页编写

商城首页App的编写,首先我们要确定我们需要确定一下大框架:


无标题绘图.jpg

如图所示,我们可以看到,首先我们需要一个内容根布局,和一个标题栏,之后是RecyclerView,之所以使用RecyclerView,是因为我们通过联网访问需要获取到实时数据。可以根据内容自定义我们需要的View,然后添加到RecyclerView中,有多少就能写多了.不用担心数据会储存不下去。好了,基本框架说完了,让我们来看看如何实现。
首先是关于ToolBar的标题栏和状态栏,因为手机本身显示内容界面有限,所以,为了保证用户能够流畅的去使用我们的app,就需要对标题栏和状态栏进行改动。
一.沉浸式状态栏:
何为沉浸式状态栏,有人可能说,像饿了吗,美团,qq那种状态栏和背景色一致,就是沉浸式状态栏,其实不然,这里参考郭霖大神的博客https://blog.csdn.net/guolin_blog/article/details/51763825
何为沉浸式,就是像游戏,电影,电视剧那样给人带来观赏体验,让人沉浸其中,不受系统UI的影响,比如像下图:

TIM截图20181004105128.png

像这样,用户不会被标题栏与状态栏所干扰,称为沉浸式状态栏。
其他的App则是被称作透明状态栏这里我简单介绍下透明状态栏如何实现
首先现将状态栏和标题栏隐藏:

 View decorView = getWindow().getDecorView();
 int option = View.SYSTEM_UI_FLAG_FULLSCREEN; 
 decorView.setSystemUiVisibility(option);
 ActionBar actionBar = getSupportActionBar();
 actionBar.hide();

效果如下:


941206-20161008131410848-553960216.png

当然,这也不是沉浸式的,只是隐藏了标题栏和状态栏,应该算是全屏模式吧,引导页就可以这么制作。下面我们修改下代码:

if (Build.VERSION.SDK_INT >= 21) {
    View decorView = getWindow().getDecorView();
    int option = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
            | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
    decorView.setSystemUiVisibility(option);
    getWindow().setNavigationBarColor(Color.TRANSPARENT);
    getWindow().setStatusBarColor(Color.TRANSPARENT);
}
ActionBar actionBar = getSupportActionBar();
actionBar.hide();

透明状态栏只有在5.0的时候才会有效果,所以我们需要对这里进行SDK的判断。接下来我们使用了SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN和SYSTEM_UI_FLAG_LAYOUT_STABLE,注意两个Flag必须要结合在一起使用,表示会让应用的主体内容占用系统状态栏的空间,最后再调用Window的setStatusBarColor()方法将状态栏设置成透明色就可以了。效果如下:


941206-20161008131302176-1520150565.png

好了,完成透明状态栏以后,我们开始编写布局代码:





    

        

            

            
        
    

布局还是很简单的,这里不再赘述了,我们所需要的就是从网络获取到json数据,然后再讲json转化为我们需要的信息展示到用户UI界面上
所以我们需要对RecyclerView进行定制。这里介绍阿里的开源框架VirtualLayout。
VirtualLayout是什么:
VirtualLayout是一个针对RecyclerView的LayoutManager扩展, 主要提供一整套布局方案和布局间的组件复用的问题。
VirtualLayout有什么作用
通过定制化的LayoutManager,接管整个RecyclerView的布局逻辑;LayoutManager管理了一系列LayoutHelper,LayoutHelper负责具体布局逻辑实现的地方;每一个LayoutHelper负责页面某一个范围内的组件布局;不同的LayoutHelper可以做不同的布局逻辑,因此可以在一个RecyclerView页面里提供异构的布局结构,这就能比系统自带的LinearLayoutManager、GridLayoutManager等提供更加丰富的能力。同时支持扩展LayoutHelper来提供更多的布局能力。默认通用布局实现,解耦所有的View和布局之间的关系: Linear, Grid, 吸顶, 浮动, 固定位置等。

① LinearLayoutHelper: 线性布局

②GridLayoutHelper: Grid布局, 支持横向的colspan

③FixLayoutHelper: 固定布局,始终在屏幕固定位置显示

④ScrollFixLayoutHelper: 固定布局,但之后当页面滑动到该图片区域才 显示, 可以用来做返回顶部或其他书签等

⑤FloatLayoutHelper:浮动布局,可以固定显示在屏幕上,但用户可以拖拽其位置

⑥ColumnLayoutHelper: 栏格布局,都布局在一排,可以配置不同列之间的宽度比值

⑦SingleLayoutHelper: 通栏布局,只会显示一个组件View

⑧OnePlusNLayoutHelper: 一拖N布局,可以配置1-5个子元素

⑨StickyLayoutHelper: stikcy布局, 可以配置吸顶或者吸底

⑩StaggeredGridLayoutHelper:瀑布流布局,可配置间隔高度/宽度

上述默认实现里可以大致分为两类:一是非fix类型布局,像线性、Grid、栏格等,它们的特点是布局在整个页面流里,随页面滚动而滚动;另一类就是fix类型的布局,它们的子节点往往不随页面滚动而滚动。

所有除布局外的组件复用,VirtualLayout将用来管理大的模块布局组合,扩展了RecyclerView,使得同一RecyclerView内的组件可以复用,减少View的创建和销毁过程。

VirtualLayout的使用
① 初始化LayoutManger

        mlayoutManager = new VirtualLayoutManager(getActivity());
        mRecyclerView.setLayoutManager(mlayoutManager);

②设置回收复用池大小,(如果一屏内相同类型的 View 个数比较多,需要设置一个合适的大小,防止来回滚动时重新创建 View):

        mviewPool = new RecyclerView.RecycledViewPool();
        mRecyclerView.setRecycledViewPool(mviewPool);
        mviewPool.setMaxRecycledViews(0, 20);

这里,因为界面样式比较多,所以,我们自定义Adapter去继承DelegateAdapter.adapter,按照需求去编写我们的界面

public class GeneralVLayoutAdapter extends DelegateAdapter.Adapter {
    private Context mContext;
    private LayoutHelper helper;
    private VirtualLayoutManager.LayoutParams params;
    private int mCount = 0;

    public GeneralVLayoutAdapter(Context context, LayoutHelper helper,
                                 VirtualLayoutManager.LayoutParams params, int count) {
        mContext = context;
        this.helper = helper;
        this.params = params;
        mCount = count;
    }

    public GeneralVLayoutAdapter(Context context, LayoutHelper helper, int count) {
        this(context, helper, null, count);
    }

    @Override
    public LayoutHelper onCreateLayoutHelper() {
        return helper;
    }

    @NonNull
    @Override
    public MainViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        return null;
    }

    @Override
    public void onBindViewHolder(@NonNull MainViewHolder mainViewHolder, int i) {
        if (params != null) {
            mainViewHolder.itemView.setLayoutParams(new VirtualLayoutManager.LayoutParams(params));
        }
    }

    @Override
    public int getItemCount() {
        return mCount;
    }

    public class MainViewHolder extends RecyclerView.ViewHolder {
        public MainViewHolder(@NonNull View itemView) {
            super(itemView);
        }
    }
}

这段代码也很简单我们需要关注一下几个方法

  • onCreateViewHolder 这个方法需要我们去重写,因为每个布局对应的viewHolder都不一样,所以需要我们在不同的布局里去重写对应的ViewHolder。

  • onBindViewHolder 这个方法也需要我们去重写,对应着ViewHolder的子项的数据进行赋值,

  • getItemCount 这个方法更简单了,它相当于告诉了RecyclerView有多少个子项,直接返回数据源的长度。因为RecyclerView已经为我们封装好了ViewHolder,所以我们的MainViewHolder直接继承RecyclerView的ViewHolder,这没啥好说的。

    private DelegateAdapter mdelegateAdapter;
    private List madapters = new LinkedList<>();
    mdelegateAdapter = new DelegateAdapter(mlayoutManager, false);
    mRecyclerView.setAdapter(mdelegateAdapter);

这里的代码需要我们综合去看,因为一个布局就对应着一个adapter,所以我们需要一个集合去添加这些adapter.下面会在代码展示,就不详细说明了。
接下来我们要准备工具,将获取到的json数据转化为UI界面,我们需要使用到OkHttp
相信很多人都使用过,因为比google推送的HttpURLConnection连接要快捷简便的多。使用方法如下,首先我们需要添加库依赖,编辑Gradle文件

implementation 'com.squareup.okhttp3:okhttp:3.11.0'

同时也要添加权限编辑manifest文件


这样我们就能访问网络,获取JSON数据了

public class OkHttpUtil {
    private static OkHttpUtil okHttpUtil = null;
    private OkHttpClient mHttpClient;
    private Request mRequest;

    public OkHttpUtil() {

    }

    public static OkHttpUtil getInstance() {
        if (okHttpUtil == null) {
            synchronized (OkHttpUtil.class) {
                if (okHttpUtil == null) {
                    okHttpUtil = new OkHttpUtil();
                }
            }
        }
        return okHttpUtil;
    }

    public void startGet(String url, final OnNetResultListener listener) {
        mHttpClient = new OkHttpClient();
        mRequest = new Request.Builder().url(url).build();
        mHttpClient.newCall(mRequest).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                listener.OnFailureListener(e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                listener.OnSuccessListener(response.body().string());
            }
        });
    }

    public void startPost(String url, String phone, String username, String password, String data,
                          final OnNetResultListener listener) {
        mHttpClient = new OkHttpClient();
        final RequestBody requestBody = new FormBody.Builder()
                .add("phone", phone)
                .add("username", username)
                .add("password", password)
                .add("regdate", data)
                .build();

        mRequest = new Request.Builder().url(url).post(requestBody).build();
        mHttpClient.newCall(mRequest).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                listener.OnFailureListener(e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                listener.OnSuccessListener(response.body().string());
            }
        });
    }

}

这是一个封装好的工具类,思路也很简单,首先我们需要一个okHttpClient的实例,因为我们需要访问网络,所以我们也需要访问URL地址,如果要访问,自然就需要Request对象,需要注意的是我们的访问请求是GET还是Post,其实GET和Post差不多,稍微复杂点,Post需要构建出一个RequestBody对象,来存储我们需要提交的参数,然后用post的方法将参数提交,接下来,就是和Get一样的操作。,好了,这样我们就成功的发送了请求。如果请求成功,我们会得到数据源,这个时候我们就需要对其解析,传送数据分为XML和JSON两种格式,这里我们主要说下如何对JSON数据的解析,XML暂且不做考虑,主要说一下如何解析JSON数据

public class JsonUtil {
    private static final int HOME_COODS_INFO = 0;
    private static final int BANK_CARD_INFO = 1;
    private static final int CLASSIFY_GOODS_INFO = 2;
    private static final int MALL_GOODS_INFO = 3;
    private static final int GOODS_DETAILS_INFO = 4;

    public List getDataFromJson(String json, int type) {
        List homeSortInfos = new ArrayList<>();
        List homeSortItemfos = new ArrayList<>();
        JSONObject mJsonObject;
        JSONArray mJsonArray;
        try {
            if (type == HOME_COODS_INFO) {
                //首页的商品信息
                mJsonObject = new JSONObject(json);
                mJsonArray = mJsonObject.getJSONArray("home_sort");
                for (int i = 0; i < mJsonArray.length(); i++) {
                    JSONObject jsonObject = (JSONObject) mJsonArray.get(i);
                    String title = jsonObject.getString("title");
                    String sortImageUrl = jsonObject.getString("sortImageUrl");
                    JSONArray jsonArray = jsonObject.getJSONArray("goods");
                    for (int j = 0; j < jsonArray.length(); j++) {
                        JSONObject jsonObject1 = (JSONObject) jsonArray.get(j);
                        String id = jsonObject1.getString("id");
                        String goodsImageUrl = jsonObject1.getString("goodsImageUrl");
                        homeSortItemfos.add(new HomeSortItemfo(id, goodsImageUrl));
                    }
                    homeSortInfos.add(new HomeSortInfo(title, sortImageUrl, homeSortItemfos));
                }
                LogUtil.d("LF1234", "homeSortInfos" + homeSortInfos);
                return homeSortInfos;
            } else if (type == BANK_CARD_INFO) {


            } else if (type == CLASSIFY_GOODS_INFO) {
                List classifyGoodsInfos = new ArrayList<>();
                mJsonObject = new JSONObject(json);
                mJsonArray = mJsonObject.getJSONArray("classifyTitle");
                for (int i = 0; i < mJsonArray.length(); i++) {
                    JSONObject jsonObject = (JSONObject) mJsonArray.get(i);
                    String title = jsonObject.getString("title");
                    String headerImageUrl = jsonObject.getString("headerImageUrl");
                    String subtitle1 = jsonObject.getString("subTitle1");
                    String subtitle2 = jsonObject.getString("suTitle");
                    JSONArray jsonArray = ((JSONObject) mJsonArray.get(i)).getJSONArray("gridImageUrls1");

                    List mGridInfos1 = new ArrayList<>();
                    List mGridInfos2 = new ArrayList<>();

                    for (int j = 0; j < jsonArray.length(); j++) {
                        JSONObject jsonObject1 = (JSONObject) jsonArray.get(j);
                        int id = jsonObject1.getInt("id");
                        String desc = jsonObject1.getString("desc");
                        String imageUrl = jsonObject1.getString("iamgeUrl");
                        mGridInfos1.add(new ClassifyGridInfo(id, desc, imageUrl));
                    }
                    JSONArray jsonArray1 = ((JSONObject) mJsonArray.get(i)).getJSONArray("gridImageUrls2");
                    for (int j = 0; j < jsonArray1.length(); j++) {
                        JSONObject jsonObject1 = (JSONObject) jsonArray1.get(j);
                        int id = jsonObject1.getInt("id");
                        String desc = jsonObject1.getString("desc");
                        String imageUrl = jsonObject1.getString("iamgeUrl");
                        mGridInfos2.add(new ClassifyGridInfo(id, desc, imageUrl));
                    }
                    classifyGoodsInfos.add(new ClassifyGoodsInfo(title, headerImageUrl, subtitle1, subtitle2, mGridInfos1, mGridInfos2));
                }
                return classifyGoodsInfos;
            } else if (type == MALL_GOODS_INFO) {
                List mallPagerInfos = new ArrayList<>();
                List bannerInfos = new ArrayList<>();
                List gridInfos = new ArrayList<>();
                List goodsInfos = new ArrayList<>();
                List mallGoodsInfos = new ArrayList<>();
                mJsonObject = new JSONObject(json);

                String singleImageUrl = mJsonObject.getString("single_image");
                mJsonArray = mJsonObject.getJSONArray("banners");
                for (int i = 0; i < mJsonArray.length(); i++) {
                    JSONObject jsonObject = (JSONObject) mJsonArray.get(i);
                    bannerInfos.add(new BannerInfo(jsonObject.getString("banner_url")));
                }
                JSONArray jsonArrayGrid = mJsonObject.getJSONArray("classifyGridItems");
                for (int i = 0; i < jsonArrayGrid.length(); i++) {
                    JSONObject jsonObject = (JSONObject) jsonArrayGrid.get(i);
                    gridInfos.add(new GridInfo(
                            jsonObject.getString("desc"),
                            jsonObject.getString("grid_url")));
                }

                JSONArray jsonArrayGoods = mJsonObject.getJSONArray("four_goods_image");
                for (int i = 0; i < jsonArrayGoods.length(); i++) {
                    JSONObject jsonObject = (JSONObject) jsonArrayGoods.get(i);
                    goodsInfos.add(new BannerInfo(jsonObject.getString("four_image_url")));
                }
                JSONArray jsonArrayHotSorts = mJsonObject.getJSONArray("hotSort");
                for (int i = 0; i < jsonArrayHotSorts.length(); i++) {
                    List mallGoodsItemInfos = new ArrayList<>();
                    JSONObject jsonObject = (JSONObject) jsonArrayHotSorts.get(i);
                    String headerImageUrl = jsonObject.getString("headerBigImage");
                    JSONArray jsonArray = jsonObject.getJSONArray("threeGoods");
                    for (int j = 0; j < jsonArray.length(); j++) {
                        JSONObject jsonObject1 = (JSONObject) jsonArray.get(j);
                        mallGoodsItemInfos.add(new MallGoodsItemInfo(
                                jsonObject1.getString("goodsItemImage"),
                                jsonObject1.getString("desc"),
                                jsonObject1.getDouble("singePrice"),
                                jsonObject1.getInt("numPeriods"),
                                jsonObject1.getDouble("price")));
                    }
                    mallGoodsInfos.add(new MallGoodsInfo(headerImageUrl, mallGoodsItemInfos));
                }
                JSONArray jsonArrayReco = mJsonObject.getJSONArray("recommends_goods");
                List recommendGoodsInfoList = new ArrayList<>();
                for (int i = 0; i < jsonArrayReco.length(); i++) {
                    JSONObject jsonObject = (JSONObject) jsonArrayReco.get(i);
                    recommendGoodsInfoList.add(new RecommendGoodsInfo(
                            jsonObject.getString("imageUrl"),
                            jsonObject.getString("desc"),
                            jsonObject.getDouble("singlePrice"),
                            jsonObject.getInt("periods"),
                            jsonObject.getDouble("totalPrice"),
                            jsonObject.getString("rate")));
                }
                mallPagerInfos.add(new MallPagerInfo(
                        bannerInfos,
                        gridInfos,
                        singleImageUrl,
                        goodsInfos,
                        mallGoodsInfos,
                        recommendGoodsInfoList));
                return mallPagerInfos;
            } else if (type == GOODS_DETAILS_INFO) {

            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return null;
    }

}

这是我自己的解析工具类使用的是JSONObject解析,很简单,我们首先创建数据模型bean,比如说,姓名,年龄,性别,可能都是在同一段节点的同一数据源中,所以我们用bean的模式,然后创建各属性的get和set方法。再用list集合去添加,然后在遍历集合的形式,将解析的数据展示到我们的界面上。下面贴出bean的代码

public class ClassifyGridInfo {
    private int id;
    private String name;
    private String imageUrl;

    public ClassifyGridInfo(int id, String name, String imageUrl) {
        this.id = id;
        this.name = name;
        this.imageUrl = imageUrl;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getImageUrl() {
        return imageUrl;
    }

    public void setImageUrl(String imageUrl) {
        this.imageUrl = imageUrl;
    }
}

再贴出JSON数据源

[{"id":"1","name":"**","imageUrl":"****"},{"id":"2","name":"**","imageUrl":"****"},
{"id":"1","name":"**","imageUrl":"****"},.....
]

这里只是举例,我们通过JSONArray将数据源转化成JSONObject,然后通过JSONObject去获取每一个元素的属性值,这里就不在赘述了。
好了,有了这些工具,下面我们来说一下关于展示界面的UI设计。
一、轮播图
轮播图是一种很常见的动态UI界面,如下图所示:

1-NTfaUB2N8OSxAGnJig333w.jpeg

这是网站上的轮播图,用户对于轮播图的反映褒贬不一,但是不可否认,它能够很直观的给用户以需求,介绍自己产品的特色,如何实现轮播图,将是我们的重点,我会使用RecyclerView去实现轮播效果。
首先,我们需要的是自定义控件属性,对,你没有听错,是自定义控件属性,因为有时候控件属性不能满足我们的需求,所以,我们需要自定义控件属性,首先,我们需要在res文件夹下values文件下新建一个attrs文件夹,用于存放我们自定义控件的属性



    
        
        
        
        
        
        
        
        
            
            
            
        
        
    

下面我们来一个个分析一下

  • 这是一个资源文件的索引名,类似Id,在代码编写时候,能够很快确定你的自定义控件属性位置。
  • attr name 是申明你想自定义控件的属性的名称 format 则是设定控件属性类型
    color:颜色值。boolean:布尔值。dimension:尺寸值。float:浮点值。integer:整型值。string:字符串。fraction:百分数。enum:枚举值。flag:位或运算。reference:参考某一资源ID。
    现在我们新建一个类去继承FragmentLayout;
public class RecyclerViewBanner extends FrameLayout {
    private static final int DEFAULT_SELECT_COLOR = 0xffffffff;//选中时的颜色
    private static final int DEFAULT_UNSELECTED_COLOR = 0X50ffffff;//未来选中时的颜色
    private RecyclerView mRecyclerView;
    private RecyclerViewAdapter adapter;
    private LinearLayout mLinearLayout;
    private OnRvBannerClickListener listener;
    private OnSwitchRvBannerListener onSwitchRvBannerListener;
    private boolean isPlaying;//是否播放
    private int startX, startY, currentIndex;//从X轴开始的位置,从Y轴开始的位置
    private int mSize;//大小
    private int mSpace;//间距
    private int mInterval;//时间间隔
    private int margin;//距离外边距的距离
    private int gravity;//位置
    private boolean isShowIndicator;//是否显示指示器
    private boolean isAutoPlaying;//是否自动播放
    private boolean isTouched;//是否触摸
    private List mData = new ArrayList<>();
    private Drawable mSelectedDrawable;//选中时背景
    private Drawable mUnSelectedDrawable;//未选中时的背景
    private Drawable selectedSrc;//选中时的资源
    private Drawable unSelectedSrc;//未选中时的资源
    private Handler mHandler = new Handler();
    private Runnable playTask = new Runnable() {
        @Override
    public void run() {
            mRecyclerView.smoothScrollToPosition(++currentIndex);//让RecyclerView平滑到指定的位置
            if (isShowIndicator) {
                changePoint();//改变圆点指示器的显示位置
            }
            mHandler.postDelayed(this, mInterval);//设置定时器
        }
    };
    public RecyclerViewBanner(@NonNull Context context) {
        super(context);
        init(context, null);
    }

    public RecyclerViewBanner(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public RecyclerViewBanner(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }
}
    private void init(final Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RecyclerViewBanner);
        mInterval = typedArray.getInt(R.styleable.RecyclerViewBanner_rvb_interval, 3000);
        isShowIndicator = typedArray.getBoolean(R.styleable.RecyclerViewBanner_rvb_showIndicator,
                true);
        isAutoPlaying = typedArray.getBoolean(R.styleable.RecyclerViewBanner_rvb_autoPlaying,
                true);
        selectedSrc = typedArray.getDrawable(R.styleable.RecyclerViewBanner_rvb_indicatorSelectedSrc);
        unSelectedSrc = typedArray.getDrawable(R.styleable.RecyclerViewBanner_rvb_indicatorUnSelectedSrc);
        mSize = typedArray.getDimensionPixelSize(R.styleable.RecyclerViewBanner_rvb_indicatorSize,
                0);
        mSpace = typedArray.getDimensionPixelSize(R.styleable.RecyclerViewBanner_rvb_indicatorSpace,
                dp2px(4));

        margin = typedArray.getDimensionPixelSize(R.styleable.RecyclerViewBanner_rvb_indicatorMargin,
                dp2px(10));
        int g = typedArray.getInt(R.styleable.RecyclerViewBanner_rvb_indicatorGravity,
                1);
        switch (g) {
            case 0:
                gravity = Gravity.START;
                break;
            case 1:
                gravity = Gravity.CENTER;
                break;
            case 2:
                gravity = Gravity.END;
                break;
            default:
                break;
        }
        if (selectedSrc == null) {
            mSelectedDrawable = gradientDrawable(DEFAULT_SELECT_COLOR);
        } else {
            if (selectedSrc instanceof ColorDrawable) {
                mSelectedDrawable = gradientDrawable(((ColorDrawable) selectedSrc).getColor());
            } else {
                mSelectedDrawable = selectedSrc;
            }
        }

        if (unSelectedSrc == null) {
            mUnSelectedDrawable = gradientDrawable(DEFAULT_UNSELECTED_COLOR);
        } else {
            if (unSelectedSrc instanceof ColorDrawable) {
                mUnSelectedDrawable = gradientDrawable(((ColorDrawable) unSelectedSrc).getColor());
            } else {
                mUnSelectedDrawable = unSelectedSrc;
            }
        }
        typedArray.recycle();//回收 TypedArray,用于后续调用时可复用之。当调用该方法后,不能再操作该变量。

        mRecyclerView = new RecyclerView(context);
        mLinearLayout = new LinearLayout(context);
        new PagerSnapHelper().attachToRecyclerView(mRecyclerView);//辅助Recycler进行滚动对齐
        adapter = new RecyclerViewAdapter();
        mRecyclerView.setAdapter(adapter);
        mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                    int first = ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPosition();
                    int last = ((LinearLayoutManager) recyclerView.getLayoutManager()).findLastVisibleItemPosition();
                    if (currentIndex != (first + last) / 2) {
                        currentIndex = (first + last) / 2;
                        changePoint();
                    }
                }
            }
        });
        mLinearLayout.setOrientation(LinearLayout.HORIZONTAL);
        mLinearLayout.setGravity(Gravity.CENTER);
        LayoutParams vpLayoutParams = new LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);

        LayoutParams linearLayoutParams = new LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);

        linearLayoutParams.gravity = Gravity.BOTTOM | gravity;
        linearLayoutParams.setMargins(margin, margin, margin, margin);

        addView(mRecyclerView, vpLayoutParams);
        addView(mLinearLayout, linearLayoutParams);
    }
/**
     * 设置间隔时间
     *
     * @param mInterval
     */
    public void setmInterval(int mInterval) {
        this.mInterval = mInterval;
    }

    /**
     * 设置是否指示器导航点
     *
     * @param showIndicator
     */
    public void setShowIndicator(boolean showIndicator) {
        isShowIndicator = showIndicator;
    }

    /**
     * 设置是否禁止滚动播放
     *
     * @param autoPlaying
     */
    public void setAutoPlaying(boolean autoPlaying) {
        isAutoPlaying = autoPlaying;
    }

    /**
     * 设置是否自动播放(上锁)
     *
     * @param playing 开始播放
     */
    private synchronized void setPlaying(boolean playing) {
        if (isAutoPlaying) {
            if (!isPlaying && playing && adapter != null && adapter.getItemCount() > 2) {
                mHandler.postDelayed(playTask, mInterval);
                isPlaying = true;
            } else if (isPlaying && !playing) {
                mHandler.removeCallbacksAndMessages(null);
                isPlaying = false;
            }
        }
    }

    //手指触摸事件
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                startX = (int) ev.getX();
                startY = (int) ev.getY();
                //阻止父层View拦截事件
                getParent().requestDisallowInterceptTouchEvent(true);
                break;
            case MotionEvent.ACTION_MOVE:
                int moveX = (int) ev.getX();
                int moveY = (int) ev.getY();
                int disX = moveX - startX;
                int disY = moveY - startY;
                boolean hasMoved = 2 * Math.abs(disX) > Math.abs(disY);
                getParent().requestDisallowInterceptTouchEvent(hasMoved);
                if (hasMoved) {
                    setPlaying(false);
                }
                break;
            case MotionEvent.ACTION_UP:
                break;
            case MotionEvent.ACTION_CANCEL:
                if (!isPlaying) {
                    isTouched = true;
                    setPlaying(true);
                }
                break;
            default:
                break;
        }
        return super.dispatchTouchEvent(ev);
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        setPlaying(true);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        setPlaying(false);
    }

    @Override
    protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
        if (visibility == GONE || visibility == INVISIBLE) {
            // 停止轮播
            setPlaying(false);
        } else if (visibility == VISIBLE) {
            // 开始轮播
            setPlaying(true);
        }
        super.onVisibilityChanged(changedView, visibility);
    }

    //创建默认指示器
    private GradientDrawable gradientDrawable(int color) {
        GradientDrawable gradientDrawable = new GradientDrawable();
        gradientDrawable.setSize(dp2px(6), dp2px(6));
        gradientDrawable.setCornerRadius(dp2px(6));
        gradientDrawable.setColor(color);
        return gradientDrawable;
    }


    /**
     * 指示器整体由数据列表容量数量的AppCompatImageView均匀分布在一个横向的LinearLayout中构成
     * 使用AppCompatImageView的好处是在Fragment中也使用Compat相关属性
     */
    private void createIndicators() {
        mLinearLayout.removeAllViews();//先动态移除所有的View
        for (int i = 0; i < mData.size(); i++) {
            ImageView imageView = new ImageView(getContext());
            LinearLayout.LayoutParams indicatorsParams = new LinearLayout.LayoutParams(
                    ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            indicatorsParams.leftMargin = mSpace / 2;
            indicatorsParams.rightMargin = mSpace / 2;
            if (mSize >= dp2px(4)) {
                indicatorsParams.width = indicatorsParams.height = mSize;
            } else {
                imageView.setMinimumHeight(dp2px(2));
                imageView.setMinimumWidth(dp2px(2));
            }
            imageView.setImageDrawable(i == 0 ? mSelectedDrawable : mUnSelectedDrawable);
            mLinearLayout.addView(imageView, indicatorsParams);
        }
    }

    //将int值转化为dp值
    private int dp2px(int dp) {
        return (int) TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP, dp, Resources.getSystem().getDisplayMetrics());
    }


    /**
     * 设置轮播数据
     *
     * @param data
     */
    public void setRvBannerData(List data) {
        setPlaying(false);
        mData.clear();
        if (null != data) {
            mData.addAll(data);
        }
        if (mData.size() > 1) {
            currentIndex = mData.size();
            adapter.notifyDataSetChanged();
            mRecyclerView.scrollToPosition(currentIndex);
            if (isShowIndicator) {
                createIndicators();
            }
            setPlaying(true);
        } else {
            currentIndex = 0;
            adapter.notifyDataSetChanged();
        }

    }

    private void changePoint() {
        if (mLinearLayout != null && mLinearLayout.getChildCount() > 0) {
            for (int i = 0; i < mLinearLayout.getChildCount(); i++) {
                ((ImageView) mLinearLayout.getChildAt(i)).setImageDrawable(
                        i == currentIndex % mData.size() ? mSelectedDrawable : mUnSelectedDrawable);
            }
        }
    }

    class RecyclerViewAdapter extends RecyclerView.Adapter {

        @NonNull
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
            SimpleDraweeView simpleDraweeView = new SimpleDraweeView(viewGroup.getContext());
            RecyclerView.LayoutParams layoutParams = new RecyclerView.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
            simpleDraweeView.setLayoutParams(layoutParams);
            simpleDraweeView.setId(R.id.rvb_banner_imageView_id);
            simpleDraweeView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            simpleDraweeView.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (listener != null) {
                        listener.OnClick(currentIndex % mData.size());
                    }
                }
            });

            return new RecyclerView.ViewHolder(simpleDraweeView) {
            };
        }

        @Override
        public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
            SimpleDraweeView draweeView = viewHolder.itemView.findViewById(R.id.rvb_banner_imageView_id);
            if (onSwitchRvBannerListener != null) {
                onSwitchRvBannerListener.switchBanner(i % mData.size(), draweeView);
            }

        }

        @Override
        public int getItemCount() {
            return mData == null ? 0 : mData.size() < 2 ? mData.size() : Integer.MAX_VALUE;
        }
    }

    public void setListener(OnRvBannerClickListener listener) {
        this.listener = listener;
    }

    public void setOnSwitchRvBannerListener(OnSwitchRvBannerListener onSwitchRvBannerListener) {
        this.onSwitchRvBannerListener = onSwitchRvBannerListener;
    }


    private class PagerSnapHelper extends LinearSnapHelper {

        @Override
        public int findTargetSnapPosition(RecyclerView.LayoutManager layoutManager, int velocityX, int velocityY) {
            //获取到将要滚动的位置targetPos
            int targetPos = super.findTargetSnapPosition(layoutManager, velocityX, velocityY);
            //找到与之最近的view
            View currentView = findSnapView(layoutManager);
            if (targetPos != RecyclerView.NOT_FOCUSABLE && null != currentView) {
                //获取最近View的位置currentPos
                int currentPos = layoutManager.getPosition(currentView);
                int first = ((LinearLayoutManager) layoutManager).findFirstCompletelyVisibleItemPosition();
                int last = ((LinearLayoutManager) layoutManager).findLastCompletelyVisibleItemPosition();
                //如果滑动的位置<最近view的位置,最近的view的位置对齐最后一个可见view的位置
                //如果滑动的位置>最近view的位置,最近的view的位置对齐第一个可见的View的位置
                currentPos = targetPos < currentPos ? last : (targetPos > currentPos ? first : currentPos);
                //如果滑动的位置<最后一个可见view的位置,将要滑动的位置对齐第一个view
                //如果滑动的位置>第一个可见view的位置,将要滑动的位置对齐最后一个view
                targetPos = targetPos < currentPos ? currentPos - 1 : (
                        targetPos > currentPos ? currentPos + 1 : currentPos);
            }
            return targetPos;
        }
    }

我们继承FrameLayout需要重写他的三个构造方法

  • public RecyclerViewBanner(@NonNull Context context) {
    super(context);
    init(context, null);
    }
  • public RecyclerViewBanner(@NonNull Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    init(context, attrs);
    }
  • public RecyclerViewBanner(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init(context, attrs);
    }

    一般来说,前两个构造函数就足够,第三个构造函数的第三个参数是用来设置默认的style样式,目前不考虑,传入参数为0即可。我们需要注意的是AttributeSet attrs这个参数,它就是需要我们传入的自定义控件属性的参数。我们通过TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RecyclerViewBanner);获取到当前自定义控件属性集合,然后对应编写默认属性。轮播图肯定是图片加指示器,有多少图片,就应该对应多少个指示器,首先我们先编写RecyclerView容器。
        mRecyclerView = new RecyclerView(context);
        mLinearLayout = new LinearLayout(context);
        new PagerSnapHelper().attachToRecyclerView(mRecyclerView);//辅助Recycler进行滚动对齐
        adapter = new RecyclerViewAdapter();
        mRecyclerView.setAdapter(adapter);
        mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                    int first = ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPosition();
                    int last = ((LinearLayoutManager) recyclerView.getLayoutManager()).findLastVisibleItemPosition();
                    if (currentIndex != (first + last) / 2) {
                        currentIndex = (first + last) / 2;
                        changePoint();
                    }
                }
            }
        });
        mLinearLayout.setOrientation(LinearLayout.HORIZONTAL);
        mLinearLayout.setGravity(Gravity.CENTER);
        LayoutParams vpLayoutParams = new LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);

        LayoutParams linearLayoutParams = new LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);

        linearLayoutParams.gravity = Gravity.BOTTOM | gravity;
        linearLayoutParams.setMargins(margin, margin, margin, margin);

        addView(mRecyclerView, vpLayoutParams);
        addView(mLinearLayout, linearLayoutParams);

这段代码我们要重点是new PagerSnapHelper().attachToRecyclerView(mRecyclerView);//辅助Recycler进行滚动对齐和对RecyclerView的滚动监听,第一个方法是通过对滑动速度定位图片位置这里推荐大家去看这篇https://www.jianshu.com/p/e54db232df62
第二个方法是防止RecyclerView停止滑动后,图片位置产生偏差,用于修正。接下来就需要编写adapter,这个相信大家已经非常熟练了。

class RecyclerViewAdapter extends RecyclerView.Adapter {

        @NonNull
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
            SimpleDraweeView simpleDraweeView = new SimpleDraweeView(viewGroup.getContext());
            RecyclerView.LayoutParams layoutParams = new RecyclerView.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
            simpleDraweeView.setLayoutParams(layoutParams);
            simpleDraweeView.setId(R.id.rvb_banner_imageView_id);
            simpleDraweeView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            simpleDraweeView.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (listener != null) {
                        listener.OnClick(currentIndex % mData.size());
                    }
                }
            });

            return new RecyclerView.ViewHolder(simpleDraweeView) {
            };
        }

        @Override
        public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
            SimpleDraweeView draweeView = viewHolder.itemView.findViewById(R.id.rvb_banner_imageView_id);
            if (onSwitchRvBannerListener != null) {
                onSwitchRvBannerListener.switchBanner(i % mData.size(), draweeView);
            }

        }

        @Override
        public int getItemCount() {
            return mData == null ? 0 : mData.size() < 2 ? mData.size() : Integer.MAX_VALUE;
        }
    }

这段代码也没有啥难点,直接使用了simpleDraweeView去填充RecyclerView布局就行了。
有人问了,如何实现轮播,这个还是很简单的,只需要利用handler定时异步操作就行了,我们还需要注意的一个地方是对于触摸的监听

 //手指触摸事件
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                startX = (int) ev.getX();
                startY = (int) ev.getY();
                //阻止父层View拦截事件
                getParent().requestDisallowInterceptTouchEvent(true);
                break;
            case MotionEvent.ACTION_MOVE:
                int moveX = (int) ev.getX();
                int moveY = (int) ev.getY();
                int disX = moveX - startX;
                int disY = moveY - startY;
                boolean hasMoved = 2 * Math.abs(disX) > Math.abs(disY);
                getParent().requestDisallowInterceptTouchEvent(hasMoved);
                if (hasMoved) {
                    setPlaying(false);
                }
                break;
            case MotionEvent.ACTION_UP:
                break;
            case MotionEvent.ACTION_CANCEL:
                if (!isPlaying) {
                    isTouched = true;
                    setPlaying(true);
                }
                break;
            default:
                break;
        }
        return super.dispatchTouchEvent(ev);
    }

对应的触摸事件是按下:ACTION_DOWN,滑动:ACTION_MOVE,抬起:ACTION_UP,结束:ACTION_CANCEL,根据这些触摸事件,判定轮播图是否停止或开始自动轮播。
这样,我们的轮播图就编写完成了。我们去Fragment添加一下吧

        SingleLayoutHelper singleLayoutHelper = new SingleLayoutHelper();
        GeneralVLayoutAdapter bannerAdapter = new GeneralVLayoutAdapter(
                getContext(), singleLayoutHelper, 1) {
            @NonNull
            @Override
            public MainViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
                View view = LayoutInflater.from(getContext()).inflate(
                        R.layout.home_pager_bannner_layout, viewGroup, false);
                return new MainViewHolder(view);
            }

            @Override
            public void onBindViewHolder(@NonNull MainViewHolder mainViewHolder, int i) {
                super.onBindViewHolder(mainViewHolder, i);
                mRecyclerViewBanner = mainViewHolder.itemView.findViewById(R.id.rvb_home_banner);
                mBannerInfos = new ArrayList<>();
                mBannerInfos.add(new BannerInfo("https://i.loli.net/2018/04/06/5ac733bc51d0a.png"));
                mBannerInfos.add(new BannerInfo("https://i.loli.net/2018/04/06/5ac735502effe.png"));
                mBannerInfos.add(new BannerInfo("https://i.loli.net/2018/04/07/5ac8459fc9b6a.png"));
                mBannerInfos.add(new BannerInfo("https://i.loli.net/2018/04/06/5ac7339ee876e.jpg"));
                mRecyclerViewBanner.setRvBannerData(mBannerInfos);
                mRecyclerViewBanner.setOnSwitchRvBannerListener(new OnSwitchRvBannerListener() {
                    @Override
                    public void switchBanner(int position, SimpleDraweeView draweeView) {
                        draweeView.setImageURI(mBannerInfos.get(position).getUrl());
                    }
                });
                mRecyclerViewBanner.setListener(new OnRvBannerClickListener() {
                    @Override
                    public void OnClick(int position) {
                        toWebActivity(UrlInfoBean.homeBannerUrls[position]);
                    }
                });
            }
        };
        madapters.add(bannerAdapter);

在这里,我们可以看到买之前我们所说的通栏布局,也就是展现一个视图的singleLayoutHelper,这里adapter就是我们上面所说的自定义的Adapter,因为每个视图对应的adapter都是不同的,所以我们需要重写onCreateViewHolderonBindViewHolder方法,然后将编写好的轮播图adapter布局添加至list结合中,至此,轮播图的界面编写完成。
下面,我们将考虑第二种布局界面的编写:网格布局 看下图

119048-18cae93d97482985.png

如图所示,上部分类导航栏就是网格布局。单个布局很简单,就是一张图片加一个TextView,



    

    


挺简单的,下面我们将其也添加至RecyclerView里面

//加载主页两行网格布局

        GridLayoutHelper gridLayoutHelper = new GridLayoutHelper(4);
        GeneralVLayoutAdapter gridAdapter = new GeneralVLayoutAdapter(
                getContext(), gridLayoutHelper, 8) {
            @NonNull
            @Override
            public MainViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
                View view = LayoutInflater.from(getContext()).inflate(
                        R.layout.home_pager_grid_two_line, viewGroup, false);
                return new MainViewHolder(view);
            }

            @Override
            public void onBindViewHolder(@NonNull MainViewHolder mainViewHolder, int i) {
                super.onBindViewHolder(mainViewHolder, i);
                ImageView imageView = mainViewHolder.itemView.findViewById(R.id.iv_home_one_grid_icon);
                TextView textView = mainViewHolder.itemView.findViewById(R.id.iv_home_one_grid_title);
                switch (i) {
                    case 0:
                        textView.setText("充值中心");
                        imageView.setImageResource(R.drawable.icon_voucher_center);
                        imageView.setOnClickListener(new MyClick(1));
                        break;
                    case 1:
                        textView.setText("手机通讯");
                        imageView.setImageResource(R.drawable.icon_phone);
                        imageView.setOnClickListener(new MyClick(2));
                        break;
                    case 2:
                        textView.setText("电影票");
                        imageView.setImageResource(R.drawable.icon_movie);
                        imageView.setOnClickListener(new MyClick(3));
                        break;
                    case 3:
                        textView.setText("全民游戏");
                        imageView.setImageResource(R.drawable.icon_game);
                        imageView.setOnClickListener(new MyClick(4));
                        break;
                    case 4:
                        textView.setText("代还信用卡");
                        imageView.setImageResource(R.drawable.icon_pay_card);
                        imageView.setOnClickListener(new MyClick(5));
                        break;
                    case 5:
                        textView.setText("现金分期");
                        imageView.setImageResource(R.drawable.icon_cash_fenqi);
                        imageView.setOnClickListener(new MyClick(6));
                        break;
                    case 6:
                        textView.setText("办信用卡");
                        imageView.setImageResource(R.drawable.icon_ban_card);
                        imageView.setOnClickListener(new MyClick(7));
                        break;
                    case 7:
                        textView.setText("全部分类");
                        imageView.setImageResource(R.drawable.icon_all_classify);
                        imageView.setOnClickListener(new MyClick(8));
                        break;
                    default:
                        break;
                }

            }
        };
        madapters.add(gridAdapter);

之前已经说明了,需要重写两个方法,就不再赘述了。这样就将网格布局添加进去了。下面是新的布局,直接上XML代码



    

        

        

        

    

    

    

        

        
    

    

        

        
    



这个XML文件也很简单,首先是Title,然后下面是一张SimpleDraweeView,最后是四张SimpleDraweeView在一起的矩形图
我们也将其添加至recyclerView中

        int count = mHomeSortInfos.size();
        GridLayoutHelper sortHelp = new GridLayoutHelper(1);
        GeneralVLayoutAdapter sortAdapter = new GeneralVLayoutAdapter(getContext(), sortHelp, count) {
            @NonNull
            @Override
            public MainViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
                View view = LayoutInflater.from(
                        getActivity()).inflate(R.layout.home_pager_goods_layout, viewGroup, false);
                return new MainViewHolder(view);
            }

            @Override
            public void onBindViewHolder(@NonNull MainViewHolder mainViewHolder, final int i) {
                super.onBindViewHolder(mainViewHolder, i);
                HomeSortInfo homeSortInfo = mHomeSortInfos.get(i);
                TextView textTitle = mainViewHolder.itemView.findViewById(R.id.tv_home_goods_title_text);
                textTitle.setText(homeSortInfo.getTitle());
                SimpleDraweeView draweeView = mainViewHolder.itemView.findViewById(R.id.iv_home_goods_bigImage);
                draweeView.setImageURI(homeSortInfo.getSortImageUrl());
                draweeView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        toWebActivity(UrlInfoBean.homeHeaderUrls[i]);
                    }
                });

                TextView textLeftImage = mainViewHolder.itemView.findViewById(R.id.tv_home_goods_title_image);
                switch (i) {
                    case 1:
                        textLeftImage.setBackground(getContext().getResources().getDrawable(R.drawable.shape_home_goods_title1));
                        break;
                    case 2:
                        textLeftImage.setBackground(getContext().getResources().getDrawable(R.drawable.shape_home_goods_title2));
                        break;
                    case 3:
                        textLeftImage.setBackground(getContext().getResources().getDrawable(R.drawable.shape_home_goods_title3));
                        break;
                    default:
                        break;
                }

                RelativeLayout heardLayout = mainViewHolder.itemView.findViewById(R.id.rl_goods_title_layout);
                heardLayout.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        startActivity(new Intent(getContext(), ClassifyGoodsActivity.class));
                        getActivity().overridePendingTransition(R.anim.activity_right_in, 0);
                    }
                });

                List sortItemfos = homeSortInfo.getmItemfos();
                SimpleDraweeView draweeView1Item1 = mainViewHolder.itemView.findViewById(R.id.iv_home_goods_item_1);
                SimpleDraweeView draweeView1Item2 = mainViewHolder.itemView.findViewById(R.id.iv_home_goods_item_2);
                SimpleDraweeView draweeView1Item3 = mainViewHolder.itemView.findViewById(R.id.iv_home_goods_item_3);
                SimpleDraweeView draweeView1Item4 = mainViewHolder.itemView.findViewById(R.id.iv_home_goods_item_4);

                draweeView1Item1.setImageURI(sortItemfos.get(0).getGoodsImageUrl());
                draweeView1Item2.setImageURI(sortItemfos.get(1).getGoodsImageUrl());
                draweeView1Item3.setImageURI(sortItemfos.get(2).getGoodsImageUrl());
                draweeView1Item4.setImageURI(sortItemfos.get(3).getGoodsImageUrl());

                draweeView1Item1.setOnClickListener(new MyClick("iv_home_goods_item_1"));
                draweeView1Item2.setOnClickListener(new MyClick("iv_home_goods_item_2"));
                draweeView1Item3.setOnClickListener(new MyClick("iv_home_goods_item_3"));
                draweeView1Item4.setOnClickListener(new MyClick("iv_home_goods_item_4"));
            }
        };

        madapters.add(sortAdapter);

        mdelegateAdapter.setAdapters(madapters);

    }

很简单吧,这样我们的布局界面就完成了,接下来,需要通过网络获取资源文件

mHomeSortInfos = new ArrayList<>();
        mHomeSortItemfos = new ArrayList<>();
        final JsonUtil jsonUtil = new JsonUtil();
        OkHttpUtil.getInstance().startGet(UrlInfoBean.homeGoodsUrl, new OnNetResultListener() {
            @Override
            public void OnSuccessListener(String result) {
                LogUtil.d("LF1234", "result=" + result);
                mHomeSortInfos = jsonUtil.getDataFromJson(result, 0);
                LogUtil.d("LF123", "mHomeSortInfos=" + mHomeSortInfos);
                Message message = mHandler.obtainMessage(0x01, mHomeSortInfos);
                mHandler.sendMessage(message);
            }

ok,下面看下效果如何。

图片发自App

嗯,有些缺陷,轮播图的图片还没有显示出来,但是大体的功能界面已经完成,后期会改进,欢迎大家评论,留言,指导,感谢大家的阅读,谢谢!

你可能感兴趣的:(关于NewHomeFragment商城首页编写)