商城項目實戰 | 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閱讀 228,646評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,595評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,560評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,035評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,814評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,224評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,301評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,444評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,988評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,804評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,998評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,544評論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,237評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,665評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,927評論 1 287
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,706評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,993評論 2 374

推薦閱讀更多精彩內容