商城项目实战 | 22.1 CircleImageView 实现我的模块

本文为菜鸟窝作者刘婷的连载。”商城项目实战”系列来聊聊仿”京东淘宝的购物商城”如何实现。

商城项目中有主要的5大模块,分别为主页模块、热门模块、分类模块、购物车模块以及我的模块,其中我的模块的主要功能是显示用户信息,里面包含了用户头像、我的订单、我的收藏、收货地址以及我的消息等,如下图所示。

效果图
效果图

因为现在很多的账号头像都是圆形头像,而且圆形头像也更为的美观些,所以本项目中我的头像也是圆形头像,那么这个圆形头像是如何实现的呢?另外我的头像下面还有个“点击登录”的文本,也就是还有登录后的显示效果吗?带着疑问往下看。

实现圆形头像

实现用户头像为圆形头像需要借助于第三方的开源控件 CircleImageView,这是一款 Android 开源显示圆形图像的控件,目前已经开源到了 GitHub 上面,具体的源代码可以进入 Github 源码查看。

1. CircleImageView 的相关属性

CircleImageView 作为自定义的开源控件,主要有四大自定义的属性,分别如下。

<declare-styleable name="CircleImageView">
        <attr name="civ_border_width" format="dimension" />
        <attr name="civ_border_color" format="color" />
        <attr name="civ_border_overlay" format="boolean" />
        <attr name="civ_fill_color" format="color" />
    </declare-styleable>

其中 civ_border_width 是设置图像外部边框宽度,civ_border_color 表示图像外部边框颜色,civ_border_overlay 是一个 boolean 值, false 代表边框是绘制在图片外部,不覆盖图片最外层,true 则是在图片之上绘制,覆盖最外层,civ_fill_color 默认为透明,表示图像填充的颜色。

2. CircleImageView 的使用方法

CircleImageView 的使用方法很简单,而且该控件在目前主流的 Android 设备上面的显示效果都很不错,和之前使用第三方框架一样的,首先要集成 CircleImageView。

2.1 Gradle 添加 CircleImageView 依赖

集成 CircleImageView 就是要在 module 的 build.gradle 文件中添加对 CircleImageView 的依赖。

dependencies {
    ......
    compile 'de.hdodenhof:circleimageview:2.1.0'

}

添加好了依赖,就可以开始使用 CircleImageView 开源控件了。

2.2 布局中添加 CircleImageView

CircleImageView 作为一款开源控件,和其他的 Android 控件的使用方法一样,直接在布局文件 layout 文件中添加该控件。

<de.hdodenhof.circleimageview.CircleImageView
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/profile_image"
    android:layout_width="96dp"
    android:layout_height="96dp"
    android:src="@drawable/profile"
    app:civ_border_width="2dp"
    app:civ_border_color="#FF000000"/>

将 CircleImageView 添加到布局文件中,同时对控件的相应属性进行设置,布局中添加好了 CircleImageView 控件后,将布局在 Activity/Fragment 中加载即可。

实现我的模块

我的模块的布局比较简单,同样的功能也不复杂,结合上文介绍的 CircleImageView 来实现我的模块。

1. 设计我的模块布局

根据上文效果图中可以看出,布局中需要有个显示图片的 ImageView以及下面4个列表,布局最好是简单化比较好,所以在这里下面的4个列表就直接使用 TextView 实现就好。

<?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"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/bg_color">

    <FrameLayout
        android:id="@+id/mine_layout_head"
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:background="?attr/colorPrimary" >

        <de.hdodenhof.circleimageview.CircleImageView
            android:id="@+id/mine_img_head"
            android:layout_width="@dimen/mine_img_head_width"
            android:layout_height="@dimen/mine_img_head_width"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="12dp"
            app:civ_border_width="2dp"
            app:civ_border_color="#FFFFFF"
            android:src="@mipmap/default_head">

        </de.hdodenhof.circleimageview.CircleImageView>

        <TextView
            android:id="@+id/mine_tv_username"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginTop="60dp"
            android:layout_marginBottom="9dp"
            android:gravity="center"
            android:text="@string/to_login"
            android:textColor="@color/white"
            android:textSize="16sp" />

    </FrameLayout>

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="none">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginTop="@dimen/mine_list_info_margin_top"
            android:orientation="vertical">

            <TextView
                android:id="@+id/mine_tv_my_orders"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="@dimen/largePadding"
                android:background="@drawable/selector_list_item"
                android:drawableLeft="@mipmap/icon_list_order"
                android:gravity="center_vertical"
                android:drawablePadding="20dp"
                android:text="@string/my_orders"
                android:textColor="@color/black"/>

            <View style="@style/line_vertical"/>

            <TextView
                android:id="@+id/mine_tv_favorite"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="@dimen/largePadding"
                android:background="@drawable/selector_list_item"
                android:drawableLeft="@mipmap/icon_favorite"
                android:gravity="center_vertical"
                android:drawablePadding="20dp"
                android:text="@string/my_favorite"
                android:textColor="@color/black"/>

            <View style="@style/line_vertical"/>

            <TextView
                android:id="@+id/mine_tv_address"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="@dimen/largePadding"
                android:background="@drawable/selector_list_item"
                android:drawableLeft="@mipmap/icon_location"
                android:gravity="center_vertical"
                android:drawablePadding="20dp"
                android:text="@string/my_addresses"
                android:textColor="@color/black"/>

            <View style="@style/line_vertical"/>

            <TextView
                android:id="@+id/mine_tv_notification"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="@dimen/largePadding"
                android:background="@drawable/selector_list_item"
                android:drawableLeft="@mipmap/icon_msg"
                android:gravity="center_vertical"
                android:drawablePadding="20dp"
                android:text="@string/my_msg"
                android:textColor="@color/black"/>

            <Button
                android:id="@+id/mine_btn_logout"
                android:text="@string/logout"
                style="@style/bigRedButton"
                android:layout_marginLeft="15dp"
                android:layout_marginRight="15dp"
                android:layout_marginTop="20dp"
                android:layout_marginBottom="20dp"
                android:layout_height="wrap_content"
                android:layout_width="match_parent"
                />

        </LinearLayout>

    </ScrollView>
</LinearLayout>

总体布局设计还是狠清楚的,最后一个 Button 则是用来退出登录的。

2. 加载用户头像

用户头像的数据也是网络数据,加载用户头像,也就是获取到图像的 URL ,然后下载图像,显示在 CircleImageView 。

Picasso.with(getActivity()).load(url).into(imgHead);

图像的下载就使用开源的 Picasso 图像加载组件。

3. 添加页面跳转

上面的头像部分完成了,下面就是下面的我的订单、我的收藏、收货地址以及我的消息的实现了,因为这四部分都是页面的跳转,所以只要为其添加好点击事件监听的处理——页面跳转。

private void initView() {

tvMyOders.setOnClickListener(this);
tvFavorite.setOnClickListener(this);
tvAddress.setOnClickListener(this);
tvNotification.setOnClickListener(this);

}

 @Override
    public void onClick(View view) {
        if(view.getId() == R.id.mine_layout_head){
            //我的订单

        }
        else if(view.getId() == R.id.mine_tv_favorite){
            //我的收藏
        }
       else if(view.getId() == R.id.mine_tv_address){
            //收货地址
        }
         else if(view.getId() == R.id.mine_tv_notification){
            //我的消息
        }
    }

这里仅仅是页面跳转,至于我的订单、我的收藏、收货地址以及我的消息四大部分的具体实现后期会继续介绍。

4.实现点击登录

点击头像上部区域,跳转到登录页面,登录的逻辑就先不要管了,登录成功之后,自然要刷新头像,并且修改头像下的用户名称。

 @Override
    public void onClick(View view) {
        if(view.getId() == R.id.mine_layout_head){
            if(CNiaoApplicaiton.getInstance().getUser() == null) {
                Intent intent = new Intent(getContext(), LoginActivity.class);
                startActivityForResult(intent, Constants.REQUEST_CODE);
            }

        }
}

Constants.REQUEST_CODE 为请求码,如果登录成功了,则会设置 setResult(RESULT_OK); 并且回到我的页面,这时候,我的页面获取到了来自登录页面的操作成功的结果码的回调来刷新用户信息,修改用户信息的方法如下。

private void showUser(UserInfo user){

        if(user!=null){

            if(!TextUtils.isEmpty(user.getLogo_url()))
                showHeadImage(user.getLogo_url());

            tvUserName.setText(user.getUsername());

            btnLoginOut.setVisibility(View.VISIBLE);
        }
        else {
            imgHead.setImageResource(R.mipmap.default_head);
            tvUserName.setText(R.string.to_login);
            btnLoginOut.setVisibility(View.GONE);
        }
    }

UserInfo 为登录后返回的用户信息类,有用户头像、昵称等成员。

5.实现退出登录

退出登录的话,就要把用户的信息清理掉,然后刷新我的里面用户信息的显示。

 CNiaoApplicaiton.getInstance().clearUser();
showUser(null);

clearUser() 方法是清理整个应用的用户信息,等于当前用户未登录,showUser(UserInfo user) 是修改用户信息的,退出了登录,就传空了,显示用户未登录时我的页面的情况。

6.效果图

运行代码,获取效果图。

上图是登录后的效果图。

最终效果

最后来展示来最终的效果吧。

进入我的页面,默认未登录,点击登录,跳转到登录页面,然后登录成功,刷新显示登录的用户头像和昵称等,再点击退出登录按钮,我的页面还原到未登录效果。因为手机号啥的不好展示,所以就直接从登录页面到登录成功后的我的页面了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,287评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,346评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,277评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,132评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,147评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,106评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,019评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,862评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,301评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,521评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,682评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,405评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,996评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,651评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,803评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,674评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,563评论 2 352

推荐阅读更多精彩内容