摘要:但由于這里僅僅是實現(xiàn)一個,因此存儲功能僅通過一個單例類來模擬實現(xiàn)。
本文旨在通過重寫GridView,配合系統(tǒng)彈窗實現(xiàn)仿今日頭條的頻道編輯頁面
注:由于代碼稍長,本文僅列出關(guān)鍵部分,完整工程請參見【https://github.com/G9YH/YHChannelEdit】
在開始講解盜版的實現(xiàn)方案前,讓我們先來看看正版與盜版的實際使用效果對比,首先是正版
接下來是盜版
當(dāng)然,在部分視圖的設(shè)計方面還是存在著不小的差異的,但這一頁面大部分基本功能已然實現(xiàn)了。那么接下來,就讓我們開始我們的模仿秀
實現(xiàn)思想事實上,我的頻道列表中,如何實現(xiàn)長按拖拽并交換頻道位置是整個頁面的核心難點(diǎn)。大致實現(xiàn)思路如下
長按某個頻道后,在該頻道上方生成一個與之相同的彈窗,同時隱藏該頻道視圖
當(dāng)手指按下時,該彈窗跟隨觸摸點(diǎn)移動
彈窗移動過程中,根據(jù)觸摸點(diǎn)交換其他頻道位置
當(dāng)手指抬起時,在觸摸點(diǎn)當(dāng)前對應(yīng)的位置處生成一個與彈窗相同的頻道視圖
拋開這一問題,其余部分的實現(xiàn)邏輯都較為簡單,這里不再贅述,下文將更會有具體實現(xiàn)的介紹
實現(xiàn)要點(diǎn) 我的頻道正如前文所言,這一部分的核心在于重寫GridView以及系統(tǒng)彈窗,那么,首先自然是系統(tǒng)彈窗權(quán)限的開啟
接下來即是GridView的重寫。首先定義了兩個常量用戶標(biāo)識當(dāng)前的模式,即編輯模式和普通模式
private static final int MODE_EDIT = 1; private static final int MODE_NORMAL = 2;
然后實現(xiàn)了OnItemLongClickListener接口
@Override public boolean onItemLongClick(AdapterView> adapterView, View view, int i, long l) { // 已處于移動模式 if (mode == MODE_EDIT) { return false; } textEdit.setText("完成"); .... // 推薦標(biāo)簽無法移動或刪除 if (i == 0) { return false; } // 判斷并獲取彈窗權(quán)限 permissionGetter.alertWindowPermissionRequest(); .... // 初始化彈窗 initWindow(); return true; }
這里需要注意到的是PermissionGetter類,我們知道,盡管在manifests中定義了系統(tǒng)彈窗的權(quán)限,但通常而言手機(jī)是需要用戶手動為app開啟相關(guān)權(quán)限的。PermissionGetter類的作用即在于此,該類通過分別處理小米、魅族以及華為等幾個較為特殊的Android系統(tǒng),基本實現(xiàn)了大部分機(jī)型的彈窗權(quán)限申請功能
/** * 判斷系統(tǒng)是否已為應(yīng)用開啟某項權(quán)限 * * @param num 權(quán)限編號 * @return 已開啟則返回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)限的申請 * 其中小米、魅族以及華為三種機(jī)型需要特殊處理 */ public void alertWindowPermission() { if (this.checkPermission(24) == 1) { Toast toast = Toast.makeText( context, "請先為您的手機(jī)開啟懸浮窗權(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) { .... } } }
在長按接口中實現(xiàn)了彈窗的初始化后,將模式mode設(shè)置為MODE_EDIT。此時即可通過重寫onTouchEvent(MovtionEvent motionEvent)方法來判斷何時進(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)手指按下時,持續(xù)更新彈窗位置,并根據(jù)其位置交換其他頻道的位置,當(dāng)然不要忘記了交換動作相應(yīng)的動畫
當(dāng)手指抬起時,將模式mode設(shè)置為MODE_NORMAL,并在彈窗當(dāng)前對應(yīng)的頻道處生成一個與彈窗相同的視圖,同時移除該彈窗視圖即可
頻道推薦這一部分的實現(xiàn)就較為簡單了,只需利用GridView展示頻道,然后實現(xiàn)OnItemClickListener接口,點(diǎn)擊時將該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(); }列表緩存
事實上,在實際開發(fā)中,通常可以采用SharedPreferences配合服務(wù)器端來實現(xiàn)我的頻道以及頻道推薦兩個列表內(nèi)容的持久化存儲。但由于這里僅僅是實現(xiàn)一個demo,因此存儲功能僅通過一個單例類ListHolder來模擬實現(xiàn)。其中ListHolder單例的實現(xiàn)方式如下,參考了我之前的一篇博客《單例模式的終極實現(xiàn)方案》
public class ListHolder { private List優(yōu)化改進(jìn)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() }
盡管到目前為止,我們已經(jīng)實現(xiàn)了大部分的基本功能,但仍與正版有部分差異,例如頻道列表內(nèi)容的存儲、部分動畫的實現(xiàn)以及視圖設(shè)計的差別等等,這一系列問題都將在之后的開發(fā)工作中繼續(xù)優(yōu)化
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/67820.html
摘要:在下沒有該問題。解決辦法部分這里隨意,需要用設(shè)定部分問題懶加載解決方法稍后補(bǔ)充參考文獻(xiàn)組件按需加載路由懶加載項目中使用將多個組件合并打包并實現(xiàn)按需加載 vue 仿今日頭條 為了增加移動端項目的經(jīng)驗,近一周通過 vue 仿寫今日頭條,以下就項目實現(xiàn)過程中遇到的問題以及解決方法給出總結(jié),有什么不正確的地方,懇請大家批評指正^?_?^!,代碼倉庫地址為 github 一、實現(xiàn)功能 首頁展示...
閱讀 1569·2021-10-14 09:43
閱讀 1561·2021-10-09 09:58
閱讀 2028·2021-09-28 09:42
閱讀 3835·2021-09-26 09:55
閱讀 1841·2021-08-27 16:23
閱讀 2843·2021-08-23 09:46
閱讀 975·2019-08-30 15:55
閱讀 1597·2019-08-30 15:54