一起擼個朋友圈吧 (Step6)- 評論對齊(點擊評論對齊)【下】

項目地址:https://github.com/razerdp/FriendCircle
《一起擼個朋友圈吧》 這是本文所處文集,所有更新都會在這個文集里面哦,歡迎關注

上篇鏈接:http://www.lxweimin.com/p/8d24f9b7a63a
下篇鏈接:http://www.lxweimin.com/p/4be8daaef3ca


因為最近忙于弄畢業(yè)設計,所以仿朋友圈這個項目暫時聽了幾天,今天花了一點時間把上一次的坑補充。
ps:因為是在太忙,服務器后臺交互還沒開始寫,所以評論暫時來說是未能實現的哦,現在僅僅是UI上的操作

按照慣例,首先上圖(圖片大小:7M,為了大小問題,色彩調的比較低,所以看起來略渣):


preview.gif

本篇實現的原理跟上篇是一致的,不過也許上一篇寫的有點亂,比較難理解,所以本篇將會一邊概括上篇的內容一邊講述如何實現本篇的內容。


Step 1:概括

在上一篇中,寫了那么多東東,其實核心思想只有一個:計算偏移量。

listview.smoothscrolltopositionfromtop這個方法執(zhí)行起來其實是分兩部的:

  • 到達指定item,使item的頂部對齊listview的頂部
  • 到達后,smoothScroll一定距離,也就是第二個參數

而我們的目標是為了讓item的底部對齊輸入框的頂部,而smoothscrolltopositionfromtop第一步已經幫我們定位好,使item的頂部對齊listview的頂部,所以我們著手的問題只是如何計算出偏移量。

又因為輸入法彈出后,實際上我們看見的內容區(qū)域是變小的,所以我們需要計算的是item的底部與輸入框頂部的差值,而這個差值就是偏移量了。

同時因為getBottom得到的是相對于父類而言的參數,所以我們只好通過item的height來動態(tài)計算(因為smoothscrolltopositionfromtop第一步會使item頂部對齊listview頂部,所以item的底部就相當于它的高度)

以上就是上一篇的概括。

總結起來就是:

  • listview定位到指定的item
  • 得到listview的height,此時的height相當于bottom
  • 得到height與可見部分的差值,這個差值就是偏移量
  • listview偏移上述步驟得到的偏移量

Step 2:評論控件對齊輸入框頂部的實現原理

通過上面的概括,其實不難得出,我們只要得到當前點擊的評論的底部再計算與可見區(qū)域底部的差值就可以了。

實際上也正是如此,但是在實現的時候我們則需要稍微處理一下。

首先看看我們的動態(tài)的底部布局:

底部布局

可以看到,我們的底部布局是RelativeLayout嵌套著LinearLayout,這第一個LinearLayout是存放點贊和評論的。然后這個LinearLayout里面又嵌套著一個LinearLayout,這個LinearLayout則是村發(fā)那個評論的。

看起來層次嵌套挺多,過度繪制妥妥的了。

不過打開微信看了看,咱就安心了。

左:微信朋友圈;右:本項目

畢竟那啥,看起來過度繪制都差不多哈哈。

上面說過,我們最終目的都是得到當前點擊的評論的底部距離可視區(qū)域的底部,同時由于我們當初的設計是將commentWidget拋了出來,所以理論上來說,我們拿到commentWidget.getBottom()就行了。

但其實不然,getTop/Bottom/Left/Right這幾個方法得到的是相對于其父布局的參數,而非在屏幕上的,所以我們需要處理一下:

比如上圖,我們需要拿到四樓相對于整個item的位置,普通的getBottom是不可行的,所以我們需要計算一下。

在布局分析那里,我們可以看到我們嵌套了好幾層,在圖中我也用不同的顏色標出來了范圍。

回到問題,我們要拿到該評論控件相對于item的位置,則需要通過其父布局的top,而父布局又因為嵌套在其他父布局里面,所以我們需要得到最外層的布局的top。在圖中表現為藍色框框的頂部。

所以我們取得當前點擊評論控件相對于item的位置方法如下:

  • 取得評論控件父布局(記為parent1)的top(圖中綠色布局),記為top1
  • 取得包含著點贊和評論布局(記為parent2)的top(即parent1.getParent(),圖中紅色布局),記為top2
  • 取得整個bottom相對于item的top,即(parent2.getParent()),記為top3
  • 取得被點擊的commentWidget的bottom(該bottom是相對于parent1的bottom)
  • 最后commentWidget的bottom相對于item來說,其y方向的值等于top1+top2+top3+bottom.

然后通過這個值減去可見區(qū)域的底部就得到了偏移值了


Step 3:代碼實現

代碼上十分簡單,本次改動僅僅只有計算偏移值的地方:

首先補充上一篇的calculateListViewOffset方法

private int calculateListViewOffset(int currentDynamicPos, CommentWidget commentWidget, int keyBoardHeight) {
        int result;
        if (screenHeight == 0) screenHeight = UIHelper.getScreenPixHeight(this);
        if (statusBarHeight == 0) statusBarHeight = UIHelper.getStatusHeight(this);

        if (commentWidget == null) {
            // 評論控件為空,證明回復的是整個動態(tài)
            result = getOffsetOfDynamic(currentDynamicPos, keyBoardHeight);
        }
        else {
            // 評論控件不空,證明回復的是評論
            result = getOffsetOfComment(currentDynamicPos, commentWidget, keyBoardHeight);
        }
        return result;
    }

然后完善我們的getOffsetOfComment方法:

 // 得到評論的偏移量
    private int getOffsetOfComment(int currentDynamicPos, CommentWidget commentWidget, int keyBoardHeight) {
        int result=0;
        int contentHeight;
        contentHeight = screenHeight - keyBoardHeight - mInputLayout.getHeight();
        try {
            //得到評論控件所在父控件(即評論的父控件)
            final LinearLayout parent = (LinearLayout) commentWidget.getParent();
            //得到評論和點贊的父控件
            final LinearLayout praiseAndCommentParent = (LinearLayout) parent.getParent();
            //得到評論和點贊的父控件的父控件
            final RelativeLayout originParent = (RelativeLayout) praiseAndCommentParent.getParent();
            //得到評論和點贊的父控件的父控件的top
            final int originParentTop = originParent.getTop();
            //得到評論和點贊的父控件的top
            final int praiseAndCommentParentTop = praiseAndCommentParent.getTop();
            //得到評論所在父控件的top
            final int parentTop = parent.getTop();
            //得到當前評論控件的底部(相對于LinearLayout)
            final int currentCommentBottom = commentWidget.getBottom();
            //則當前評論控件相對于item來說,其底部=父類LinearLayout.top+當前控件的底部
            final int currentCommentOffset = originParentTop + praiseAndCommentParentTop + parentTop + currentCommentBottom;

            //則偏移量等于offset-contentheight
            result = currentCommentOffset - contentHeight;
        } catch (Exception e) {
            e.printStackTrace();
            Log.e("FriendCircleDemoAct","也許是空指針也許是cast錯誤哦");
        }
        return -result;
    }

相關代碼都寫了注釋了,因為忽然發(fā)現,本項目的注釋稍微少了點。

本篇就到此結束了。

到現在為止,我們的朋友圈實現了以下幾個功能:

  • 展示數據
  • 點贊/取消點贊(包括點贊的彈窗、點贊時的動畫)
  • 評論(點擊動態(tài)的評論對齊/點擊評論控件對齊)

理論上,一個初始的朋友圈功能就差不多了。

接下來我們將會實現朋友圈的圖片查看,當然,包括動畫-V-。

最后還是那句話,如果您有好的想法或者改進方法或者建議,在下非常歡迎在評論區(qū)留下您的腳印,當然如果能提交PR,那是最好不過了,如果您喜歡本項目,可否求個star-V-

ps:評論方面與服務器后臺請求部分將不會再寫文章了,完成后將會在別的文章一筆帶過。
ps2:最近我重新弄了個阿里云,所以以前的服務器地址失效了喲,如果需要服務器地址,依然是簡信我或者加我的QQ(164701463)

【END】

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容