<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # **漫畫閱讀(滑動翻頁)** **本節說的是哪一模塊?** 漫畫閱讀模塊 **本節要講的知識點有哪些?** 1.滑動翻頁特效——左滑動,右滑動。 2.圖片切割裁剪——適應手機屏幕。 **標題索引:** 翻頁特效的實現原理 recyclerview的簡單介紹 recyclerview能實現哪些效果 recyclerview的簡單用法 圖片切割裁剪原理 ImageVIew準備工作 裁剪圖片的原理 快速裁剪圖片——使用框架 ## **翻頁特效** 首先,滑動翻頁這種功能挺基礎的,通常有多種做法,ViewPager、LIstVIew、RecyclerView,GridView等等,即使用Linerlayout也可以。 我們不要糾結使用哪一種方式,去實現翻頁特效, 當前,最重要的是,根據我以及諸位很多同行的經驗來看,使用RecyclerVIew是大勢所趨,也是最方便快捷的。 優點不展開講了。在此處,只需要知道,Android有很多方式,都可以實現滑動翻頁效果;并且,使用RecyclerVIew去實現滑動特效,是比較優秀的做法。 首先,我們來看,RecyclerView能實現哪些常見的UI布局: **特效1:上下滑動特效(經典上下list列表)** ![](https://box.kancloud.cn/a2344be3ff367005c33ee87dc4479c49_273x488.png) **特效2:左右滑動特效(經典的手指觸摸水平滑動列表)** ![](https://box.kancloud.cn/ad2bec5898a464d701cb3e93a11ccf0f_527x519.png) ok,上述兩點只是RecyclerView最普通的用法,但是已經足夠理解我們今天探討的話題了——快點想想,我們本節討論的核心內容是啥? 左右滑動特效! > 注:在此次研究的漫畫APP中,閱讀模塊對應的文件是ReaderActivity,在該文件當中也創建、使用了RecyclerVIew。 我們從漫畫APP的閱讀模塊當中,學習本節的核心內容: ## RecyclerView的簡單使用 以漫畫APP的閱讀模塊ReaderActivity為例,我們抓住RecyclerVIew出現的身影,仔細探究滑動翻頁的實現過程: ~~~ public abstract class ReaderActivity extends BaseActivity implements OnTapGestureListener, OnProgressChangeListener, OnLazyLoadListener, ReaderView { ..... @BindView(R.id.reader_recycler_view) RecyclerView mRecyclerView; ...... protected PreCacheLayoutManager mLayoutManager; protected ReaderAdapter mReaderAdapter; @Override protected void initView() { ..... initLayoutManager(); initReaderAdapter(); mRecyclerView.setItemAnimator(null); mRecyclerView.setLayoutManager(mLayoutManager); mRecyclerView.setAdapter(mReaderAdapter); mRecyclerView.setItemViewCacheSize(2); mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { mLastDx = dx; mLastDy = dy; } }); .... } .... private void initLayoutManager() { mLayoutManager = new PreCacheLayoutManager(this); mLayoutManager.setOrientation(turn == PreferenceManager.READER_TURN_ATB ? LinearLayoutManager.VERTICAL : LinearLayoutManager.HORIZONTAL); mLayoutManager.setReverseLayout(turn == PreferenceManager.READER_TURN_RTL); mLayoutManager.setExtraSpace(2); } ..... private void initReaderAdapter() { .... mReaderAdapter = new ReaderAdapter(this, new LinkedList<ImageUrl>()); ..... } } ~~~ 1. 1.@BindView(R.id.reader_recycler_view) RecyclerView mRecyclerView;是RecyclerView初始化的過程,前面@BindView是高級框架的用法,本質結果,等同于findViewById。在這里,我們只需要知道,RecyclerView第一次出現,就已經從實例化對象了。 2. 2.mRecyclerView.setAdapter(mReaderAdapter); RecyclerView通過setAdapter()設置了每一個子元素的“顯示器”(把RecyclerView的每一個list子元素,當成一個小的顯示器,Adapter的作用,就是存儲、綁定、將這些數據顯示到RecyclerVIew),漫畫圖片,就是在此時,被附著到RecyclerView上的。 3. 3.mRecyclerView.setLayoutManager(mLayoutManager);RecyclerView通過setLayoutManager()函數,可以設置列表顯示的方向:即水平左右滑動;豎直上下滑動。 4. 4.具體的,閱讀頁面滑動的方向,是由LayoutManager對象決定的,我們可以在此處看到:mLayoutManager.setOrientation(turn == PreferenceManager.READER_TURN_ATB ? LinearLayoutManager.VERTICAL : LinearLayoutManager.HORIZONTAL); > 新手可能看不到此處的含義,但至少VERTICAL和HORIZONTAL查查字典還是可以理解的:水平和豎直。 水平顯示RecyclerView每一個子元素,產生的效果,就是左右滑動的翻頁特效; 豎直顯示,產生的效果,將是普通新聞列表頁那樣,上下滑動翻頁。 至此,我們抓住了左右滑動的兩個核心:RecyclerView和LayoutManager,前者提供了多個子元素**滑動**的能力,后者提供了控制布局**方向**的能力。 所以說,要實現閱讀滑動翻頁特效,兩者缺一不可。 而回到閱讀模塊最主要的功能:顯示漫畫圖片上。 在顯示漫畫圖片這的實現過程中,功勞最大的,當屬于第二步,**傳遞給RecyclerView的Adapter**,是它,控制了view顯示的每一個子元素,也是它,設置了子元素與屏幕寬高同樣大小,每一個子元素占滿屏幕,左右滑動,看上去,就等同于翻頁瀏覽了。 接著,我們來聊圖片切割裁剪技術 ## **圖片切割裁剪** 要討論圖片切割,必須先討論圖片的容器——ImageView ImageView,首先并沒有包含任何圖片相關的屬性,換言之,如果沒有一張jpg圖片,ImageView不可能自己顯示出一些圖像的。(當然還有Canvas,先不細談) 先說ImageView默認的切割方式 假設ImageVIew寬和高分別為360和720,圖片文件對應的Bitmap對象寬和高為480和920. ImageView直接setbitmap() ![](https://box.kancloud.cn/a96f5fe550fea0524264b0d4a9090d32_745x565.png) 顯示的結果是: ![](https://box.kancloud.cn/674dfcdece828fdd9001b2c0f6b56909_368x554.png) 圖很丑陋,但是言簡意賅。是的,只有藍色方框里的內容,會被顯示到ImageView上,其他部分,只是因為“ImageVIew放不下了”,而沒有顯示出來—— 這就造成了圖片被切割裁剪的視覺效果,也是第一種實現方式,通過控制ImageView的屬性(動態設置其寬高),來實現切割、裁剪效果。 ImageView有很多屬性和函數,都可以動態的實現切割、裁剪效果:比如matrix矩陣,設置圖片Bitmap縮放的比例;比如通過setWidth和setHeight,設置Imageview的寬和高度,匹配圖片的寬度和高度; 既然ImageView可以縮放、匹配圖片Bitmap的寬度和高度,那么是否轉換思路,縮放圖片源Bitmap試試呢? 答案是肯定的,當然可以,以及推薦這樣做 直接裁剪圖片Bitmap,可以實現這樣的效果: ![](https://box.kancloud.cn/420af098429d408eecad784fe93e8c2d_756x420.png) 可以看到,圖片Bitmap,默認寬高大于ImageView,直接顯示至ImageVIew會被裁剪,以至于ImageViw只能顯示部分圖片內容; 而在我們對Bitmap對象處理之后,圖片恰好顯示至手機屏幕上——當然,左右留白是允許的,也是等比縮放圖片Bitmap不得不面對的結果,這也是最好裁剪縮放效果了。 換一張圖,我們試試 ![](https://box.kancloud.cn/872abe7e46e63e1d3b5a0e5a4fa13837_747x336.png) 總結,為了使得圖片完美的裁剪,匹配手機屏幕的寬高,我們必須采用等比裁剪的方式: 保持圖片的長邊與手機屏幕一致性,同比例縮放圖片源Bitmap的寬高。 ok 那么我們如何通過縮放Bitmap,達到裁剪、切割的效果呢? 假設我們讀取一張res/drawable/目錄下的圖片文件 ~~~ /** * 通過資源id轉化成Bitmap * * @param context * @param resId * @return */ public static Bitmap ReadBitmapById(Context context, int resId) { BitmapFactory.Options opt = new BitmapFactory.Options(); opt.inPreferredConfig = Bitmap.Config.RGB_565; opt.inPurgeable = true; opt.inInputShareable = true; InputStream is = context.getResources().openRawResource(resId); return BitmapFactory.decodeStream(is, null, opt); } ~~~ 通過ReadBitmapById,我們獲取到了圖片對象BItmap 獻上一段代碼,我們直接壓縮圖片的寬度和高度 `` /** * 按照一定的寬高比例裁剪圖片 * * @param bitmap * @param num1 * 長邊的比例 * @param num2 * 短邊的比例 * @return */ public static Bitmap ImageCrop(Bitmap bitmap, int num1, int num2, boolean isRecycled) { if (bitmap == null) { return null; } int w = bitmap.getWidth(); // 得到圖片的寬,高 int h = bitmap.getHeight(); int retX, retY; int nw, nh; if (w > h) { if (h > w * num2 / num1) { nw = w; nh = w * num2 / num1; retX = 0; retY = (h - nh) / 2; } else { nw = h * num1 / num2; nh = h; retX = (w - nw) / 2; retY = 0; } } else { if (w > h * num2 / num1) { nh = h; nw = h * num2 / num1; retY = 0; retX = (w - nw) / 2; } else { nh = w * num1 / num2; nw = w; retY = (h - nh) / 2; retX = 0; } } Bitmap bmp = Bitmap.createBitmap(bitmap, retX, retY, nw, nh, null, false); if (isRecycled && bitmap != null && !bitmap.equals(bmp) && !bitmap.isRecycled()) { bitmap.recycle(); bitmap = null; } return bmp;// Bitmap.createBitmap(bitmap, retX, retY, nw, nh, null, // false); } `` 通過ImageCrop()我們可以裁剪切割圖片Bitmap的寬度和高度。 這樣,就完美得實現了圖片裁剪和切割。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看