項目地址:https://github.com/razerdp/FriendCircle
《一起擼個朋友圈吧》 這是本文所處文集,所有更新都會在這個文集里面哦,歡迎關注
上篇鏈接:http://www.lxweimin.com/p/8d24f9b7a63a
下篇鏈接:http://www.lxweimin.com/p/4be8daaef3ca
因為最近忙于弄畢業(yè)設計,所以仿朋友圈這個項目暫時聽了幾天,今天花了一點時間把上一次的坑補充。
ps:因為是在太忙,服務器后臺交互還沒開始寫,所以評論暫時來說是未能實現的哦,現在僅僅是UI上的操作
按照慣例,首先上圖(圖片大小:7M,為了大小問題,色彩調的比較低,所以看起來略渣):
本篇實現的原理跟上篇是一致的,不過也許上一篇寫的有點亂,比較難理解,所以本篇將會一邊概括上篇的內容一邊講述如何實現本篇的內容。
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】