成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

重寫(xiě)GridView實(shí)現(xiàn)仿今日頭條的頻道編輯頁(yè)(1)

張憲坤 / 3341人閱讀

摘要:但由于這里僅僅是實(shí)現(xiàn)一個(gè),因此存儲(chǔ)功能僅通過(guò)一個(gè)單例類(lèi)來(lái)模擬實(shí)現(xiàn)。

本文旨在通過(guò)重寫(xiě)GridView,配合系統(tǒng)彈窗實(shí)現(xiàn)仿今日頭條的頻道編輯頁(yè)面

注:由于代碼稍長(zhǎng),本文僅列出關(guān)鍵部分,完整工程請(qǐng)參見(jiàn)【https://github.com/G9YH/YHChannelEdit】

在開(kāi)始講解盜版的實(shí)現(xiàn)方案前,讓我們先來(lái)看看正版與盜版的實(shí)際使用效果對(duì)比,首先是正版

接下來(lái)是盜版

當(dāng)然,在部分視圖的設(shè)計(jì)方面還是存在著不小的差異的,但這一頁(yè)面大部分基本功能已然實(shí)現(xiàn)了。那么接下來(lái),就讓我們開(kāi)始我們的模仿秀

實(shí)現(xiàn)思想

事實(shí)上,我的頻道列表中,如何實(shí)現(xiàn)長(zhǎng)按拖拽并交換頻道位置是整個(gè)頁(yè)面的核心難點(diǎn)。大致實(shí)現(xiàn)思路如下

長(zhǎng)按某個(gè)頻道后,在該頻道上方生成一個(gè)與之相同的彈窗,同時(shí)隱藏該頻道視圖

當(dāng)手指按下時(shí),該彈窗跟隨觸摸點(diǎn)移動(dòng)

彈窗移動(dòng)過(guò)程中,根據(jù)觸摸點(diǎn)交換其他頻道位置

當(dāng)手指抬起時(shí),在觸摸點(diǎn)當(dāng)前對(duì)應(yīng)的位置處生成一個(gè)與彈窗相同的頻道視圖

拋開(kāi)這一問(wèn)題,其余部分的實(shí)現(xiàn)邏輯都較為簡(jiǎn)單,這里不再贅述,下文將更會(huì)有具體實(shí)現(xiàn)的介紹

實(shí)現(xiàn)要點(diǎn) 我的頻道

正如前文所言,這一部分的核心在于重寫(xiě)GridView以及系統(tǒng)彈窗,那么,首先自然是系統(tǒng)彈窗權(quán)限的開(kāi)啟

接下來(lái)即是GridView的重寫(xiě)。首先定義了兩個(gè)常量用戶(hù)標(biāo)識(shí)當(dāng)前的模式,即編輯模式和普通模式

private static final int MODE_EDIT = 1;
private static final int MODE_NORMAL = 2;

然后實(shí)現(xiàn)了OnItemLongClickListener接口

    @Override
    public boolean onItemLongClick(AdapterView adapterView, View view, int i, long l) {
        //  已處于移動(dòng)模式
        if (mode == MODE_EDIT) {
            return false;
        }
 
        textEdit.setText("完成");
 
        ....
 
        //  推薦標(biāo)簽無(wú)法移動(dòng)或刪除
        if (i == 0) {
            return false;
        }
 
        //  判斷并獲取彈窗權(quán)限
        permissionGetter.alertWindowPermissionRequest();
 
        ....
 
        //  初始化彈窗
        initWindow();
 
        return true;
    }

這里需要注意到的是PermissionGetter類(lèi),我們知道,盡管在manifests中定義了系統(tǒng)彈窗的權(quán)限,但通常而言手機(jī)是需要用戶(hù)手動(dòng)為app開(kāi)啟相關(guān)權(quán)限的。PermissionGetter類(lèi)的作用即在于此,該類(lèi)通過(guò)分別處理小米、魅族以及華為等幾個(gè)較為特殊的Android系統(tǒng),基本實(shí)現(xiàn)了大部分機(jī)型的彈窗權(quán)限申請(qǐng)功能

/**
 * 判斷系統(tǒng)是否已為應(yīng)用開(kāi)啟某項(xiàng)權(quán)限
 *
 * @param num 權(quán)限編號(hào)
 * @return 已開(kāi)啟則返回0,否則返回1
 */
private int checkPermission(int num) {
    int version = Build.VERSION.SDK_INT;
    if (version >= 19) {
        ....
    }
    return -1;
}
 
....
 
/**
 * Android 6.0之后的手機(jī)需要進(jìn)行彈窗權(quán)限的申請(qǐng)
 * 其中小米、魅族以及華為三種機(jī)型需要特殊處理
 */
public void alertWindowPermission() {
    if (this.checkPermission(24) == 1) {
        Toast toast = Toast.makeText(
                context, "請(qǐng)先為您的手機(jī)開(kāi)啟懸浮窗權(quán)限", Toast.LENGTH_SHORT);
        toast.show();
        //  處理小米手機(jī)權(quán)限
        if ("Xiaomi".equals(Build.MANUFACTURER)) {
            ....
            }
        }
        //  處理魅族手機(jī)權(quán)限
        else if ("Meizu".equals(Build.MANUFACTURER)) {
            ....
        }
        //  處理華為手機(jī)權(quán)限
        else if ("Huawei".equals(Build.MANUFACTURER)) {
            ....
        }
        //  處理其他手機(jī)權(quán)限
        else if (Build.VERSION.SDK_INT >= 23) {
            ....
        }
    }
}

在長(zhǎng)按接口中實(shí)現(xiàn)了彈窗的初始化后,將模式mode設(shè)置為MODE_EDIT。此時(shí)即可通過(guò)重寫(xiě)onTouchEvent(MovtionEvent motionEvent)方法來(lái)判斷何時(shí)進(jìn)行彈窗的更新以及關(guān)閉等工作

@Override
public boolean onTouchEvent(MotionEvent motionEvent) {
    switch (motionEvent.getAction()) {
        case MotionEvent.ACTION_DOWN:
            break;
        case MotionEvent.ACTION_MOVE:
            if (mode == MODE_EDIT) {
                updateWindow(motionEvent);
            }
            break;
        case MotionEvent.ACTION_UP:
            if (mode == MODE_EDIT) {
                closeWindow();
            }
            break;
    }
    return super.onTouchEvent(motionEvent);
}

當(dāng)手指按下時(shí),持續(xù)更新彈窗位置,并根據(jù)其位置交換其他頻道的位置,當(dāng)然不要忘記了交換動(dòng)作相應(yīng)的動(dòng)畫(huà)

當(dāng)手指抬起時(shí),將模式mode設(shè)置為MODE_NORMAL,并在彈窗當(dāng)前對(duì)應(yīng)的頻道處生成一個(gè)與彈窗相同的視圖,同時(shí)移除該彈窗視圖即可

頻道推薦

這一部分的實(shí)現(xiàn)就較為簡(jiǎn)單了,只需利用GridView展示頻道,然后實(shí)現(xiàn)OnItemClickListener接口,點(diǎn)擊時(shí)將該item移除并添加至我的頻道視圖中即可

@OnItemClick(R.id.grid_recommend) void gridRecommend(int position) {
    String string = listHolder.getRecommendList().get(position);
    //  我的頻道中增加標(biāo)簽
    listHolder.getMineList().add(string);
    //  頻道推薦中刪除標(biāo)簽
    listHolder.getRecommendList().remove(position);
 
    //  更新各頻道數(shù)據(jù)
    mineAdapter.moveNotifyDataSetChanged(false, -1);
    recommendAdapter.notifyDataSetChanged();
}
列表緩存

事實(shí)上,在實(shí)際開(kāi)發(fā)中,通??梢圆捎肧haredPreferences配合服務(wù)器端來(lái)實(shí)現(xiàn)我的頻道以及頻道推薦兩個(gè)列表內(nèi)容的持久化存儲(chǔ)。但由于這里僅僅是實(shí)現(xiàn)一個(gè)demo,因此存儲(chǔ)功能僅通過(guò)一個(gè)單例類(lèi)ListHolder來(lái)模擬實(shí)現(xiàn)。其中ListHolder單例的實(shí)現(xiàn)方式如下,參考了我之前的一篇博客《單例模式的終極實(shí)現(xiàn)方案》

public class ListHolder {
    private List mineList = new ArrayList<>();
    private List recommendList = new ArrayList<>();
 
    private static class Instance {
        private static ListHolder instance = new ListHolder();
    }
 
    private ListHolder() {
    }
 
    public static ListHolder getInstance() {
        return Instance.instance;
    }
 
    public get() & set()
}
優(yōu)化改進(jìn)

盡管到目前為止,我們已經(jīng)實(shí)現(xiàn)了大部分的基本功能,但仍與正版有部分差異,例如頻道列表內(nèi)容的存儲(chǔ)、部分動(dòng)畫(huà)的實(shí)現(xiàn)以及視圖設(shè)計(jì)的差別等等,這一系列問(wèn)題都將在之后的開(kāi)發(fā)工作中繼續(xù)優(yōu)化

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/67820.html

相關(guān)文章

  • vue 仿今日頭條

    摘要:在下沒(méi)有該問(wèn)題。解決辦法部分這里隨意,需要用設(shè)定部分問(wèn)題懶加載解決方法稍后補(bǔ)充參考文獻(xiàn)組件按需加載路由懶加載項(xiàng)目中使用將多個(gè)組件合并打包并實(shí)現(xiàn)按需加載 vue 仿今日頭條 為了增加移動(dòng)端項(xiàng)目的經(jīng)驗(yàn),近一周通過(guò) vue 仿寫(xiě)今日頭條,以下就項(xiàng)目實(shí)現(xiàn)過(guò)程中遇到的問(wèn)題以及解決方法給出總結(jié),有什么不正確的地方,懇請(qǐng)大家批評(píng)指正^?_?^!,代碼倉(cāng)庫(kù)地址為 github 一、實(shí)現(xiàn)功能 首頁(yè)展示...

    ShowerSun 評(píng)論0 收藏0
  • vue 仿今日頭條

    摘要:在下沒(méi)有該問(wèn)題。解決辦法部分這里隨意,需要用設(shè)定部分問(wèn)題懶加載解決方法稍后補(bǔ)充參考文獻(xiàn)組件按需加載路由懶加載項(xiàng)目中使用將多個(gè)組件合并打包并實(shí)現(xiàn)按需加載 vue 仿今日頭條 為了增加移動(dòng)端項(xiàng)目的經(jīng)驗(yàn),近一周通過(guò) vue 仿寫(xiě)今日頭條,以下就項(xiàng)目實(shí)現(xiàn)過(guò)程中遇到的問(wèn)題以及解決方法給出總結(jié),有什么不正確的地方,懇請(qǐng)大家批評(píng)指正^?_?^!,代碼倉(cāng)庫(kù)地址為 github 一、實(shí)現(xiàn)功能 首頁(yè)展示...

    Sourcelink 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<