Skip to content
This repository was archived by the owner on Jul 25, 2024. It is now read-only.

Commit 8444666

Browse files
committed
Float sticky headers below toolbar.
will be useful when user scroll up.
1 parent 819afff commit 8444666

File tree

5 files changed

+76
-7
lines changed

5 files changed

+76
-7
lines changed

app/src/main/java/com/zulip/android/activities/ZulipActivity.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
import android.support.v7.app.AppCompatDelegate;
5454
import android.support.v7.app.NotificationCompat;
5555
import android.support.v7.widget.LinearLayoutManager;
56+
import android.support.v7.widget.RecyclerView;
5657
import android.support.v7.widget.Toolbar;
5758
import android.text.Editable;
5859
import android.text.TextUtils;
@@ -225,6 +226,8 @@ public void onReceive(Context contenxt, Intent intent) {
225226
private ImageView addFileBtn;
226227
//
227228
private String streamSearchFilterKeyword = "";
229+
private RecyclerView.ViewHolder viewHolder;
230+
private boolean isActionBarShown = true;
228231

229232
private SimpleCursorAdapter.ViewBinder peopleBinder = new SimpleCursorAdapter.ViewBinder() {
230233
@Override
@@ -1926,6 +1929,35 @@ public void setLayoutBehaviour(LinearLayoutManager linearLayoutManager, Recycler
19261929
topSnackBar.setMessagesAdapter(adapter);
19271930
}
19281931

1932+
/**
1933+
* called when action bar hides
1934+
* due to down scroll in message list
1935+
*/
1936+
public void onHideActionBar() {
1937+
isActionBarShown = false;
1938+
try {
1939+
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) viewHolder.itemView.getLayoutParams();
1940+
layoutParams.setMargins(0, 0, 0, 0);
1941+
viewHolder.itemView.requestLayout();
1942+
} catch (NullPointerException ignored) {
1943+
}
1944+
}
1945+
1946+
1947+
/**
1948+
* called when action bar is shown
1949+
* due to up scroll in message list
1950+
*/
1951+
public void onShowActionBar() {
1952+
isActionBarShown = true;
1953+
try {
1954+
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) viewHolder.itemView.getLayoutParams();
1955+
layoutParams.setMargins(0, mToolbarHeightInPx, 0, 0);
1956+
viewHolder.itemView.requestLayout();
1957+
} catch (NullPointerException ignored) {
1958+
}
1959+
}
1960+
19291961
@Override
19301962
public void onBackPressed() {
19311963
//check for drawer
@@ -2636,11 +2668,21 @@ public MessageListFragment getCurrentMessageList() {
26362668
}
26372669
}
26382670

2671+
/**
2672+
* Store floating message header
2673+
* useful when message list get's scrolled
2674+
* @param viewHolder floating message header
2675+
*/
2676+
public void setViewHolder(RecyclerView.ViewHolder viewHolder) {
2677+
this.viewHolder = viewHolder;
2678+
}
2679+
26392680
// Intent Extra constants
26402681
public enum Flag {
26412682
RESET_DATABASE,
26422683
}
26432684

2685+
26442686
private boolean isTablet() {
26452687
return isTablet(this);
26462688
}
@@ -2649,5 +2691,15 @@ public static boolean isTablet(Context context) {
26492691
return context.getResources().getBoolean(R.bool.isTablet);
26502692
}
26512693

2694+
2695+
/**
2696+
* get top margin for floating header
2697+
*
2698+
* @return toolbar height if it is visible else 0
2699+
*/
2700+
public int getFloatingHeaderTopMargin() {
2701+
return (isActionBarShown) ? mToolbarHeightInPx : 0;
2702+
}
2703+
26522704
}
26532705

app/src/main/java/com/zulip/android/util/RemoveViewsOnScroll.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import android.widget.LinearLayout;
1818

1919
import com.zulip.android.R;
20+
import com.zulip.android.ZulipApp;
2021
import com.zulip.android.activities.RecyclerMessageAdapter;
2122

2223
/**
@@ -89,6 +90,7 @@ private void hideView(final View view) {
8990
;
9091
if (view instanceof AppBarLayout) {
9192
y = -1 * view.getHeight();
93+
ZulipApp.get().getZulipActivity().onHideActionBar();
9294
} else if (view instanceof LinearLayout) {
9395
y = 0;
9496
}
@@ -125,8 +127,13 @@ public void onAnimationRepeat(Animator animator) {
125127
@SuppressLint("NewApi")
126128
public void showView(final View view) {
127129
mIsShowing = true;
130+
float translationY = toolbarHeight;
131+
if ((view.getId() == R.id.appBarLayout || view instanceof FloatingActionButton)) {
132+
ZulipApp.get().getZulipActivity().onShowActionBar();
133+
translationY = 0;
134+
}
128135
ViewPropertyAnimator animator = view.animate()
129-
.translationY((view.getId() == R.id.appBarLayout || view instanceof FloatingActionButton) ? 0 : toolbarHeight)
136+
.translationY(translationY)
130137
.setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR)
131138
.setDuration(200);
132139

app/src/main/java/com/zulip/android/viewholders/stickyheaders/GetStickyHeaderPosition.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ void setHeaderPositions(List<Integer> headerPositions) {
5858
this.headerPositions = headerPositions;
5959
}
6060

61-
void updateHeaderState(int firstVisiblePosition, Map<Integer, View> visibleHeaders,
62-
RetrieveHeaderView retrieveHeaderView) {
61+
RecyclerView.ViewHolder updateHeaderState(int firstVisiblePosition, Map<Integer, View> visibleHeaders,
62+
RetrieveHeaderView retrieveHeaderView) {
6363
int headerPositionToShow = getHeaderPositionToShow(
6464
firstVisiblePosition, visibleHeaders.get(firstVisiblePosition));
6565
View headerToCopy = visibleHeaders.get(headerPositionToShow);
@@ -70,11 +70,12 @@ void updateHeaderState(int firstVisiblePosition, Map<Integer, View> visibleHeade
7070
lastBoundPosition = INVALID_POSITION;
7171
} else {
7272
// We don't want to attach yet if header view is not at edge
73-
if (checkMargins && headerAwayFromEdge(headerToCopy)) return;
73+
if (checkMargins && headerAwayFromEdge(headerToCopy)) return null;
7474
RecyclerView.ViewHolder viewHolder =
7575
retrieveHeaderView.getViewHolderForPosition(headerPositionToShow);
7676
attachHeader(viewHolder, headerPositionToShow);
7777
lastBoundPosition = headerPositionToShow;
78+
return viewHolder;
7879
}
7980
} else if (checkMargins) {
8081
/*
@@ -87,6 +88,7 @@ void updateHeaderState(int firstVisiblePosition, Map<Integer, View> visibleHeade
8788
}
8889
}
8990
checkHeaderPositions(visibleHeaders);
91+
return null;
9092
}
9193

9294
// This checks visible headers and their positions to determine if the sticky header needs

app/src/main/java/com/zulip/android/viewholders/stickyheaders/StickyLayoutManager.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@
44

55
import android.content.Context;
66
import android.support.annotation.Nullable;
7+
import android.support.design.widget.CoordinatorLayout;
78
import android.support.v7.widget.LinearLayoutManager;
89
import android.support.v7.widget.RecyclerView;
10+
import android.util.Log;
911
import android.view.View;
1012

11-
13+
import com.zulip.android.ZulipApp;
14+
import com.zulip.android.util.RemoveViewsOnScroll;
1215
import com.zulip.android.viewholders.MessageHeaderParent;
1316
import com.zulip.android.viewholders.stickyheaders.interfaces.RetrieveHeaderView;
1417
import com.zulip.android.viewholders.stickyheaders.interfaces.StickyHeaderHandler;
@@ -75,8 +78,11 @@ private void cacheHeaderPositions() {
7578
public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
7679
int scroll = super.scrollVerticallyBy(dy, recycler, state);
7780
if (Math.abs(scroll) > 0) {
78-
positioner.updateHeaderState(
81+
RecyclerView.ViewHolder viewHolder = positioner.updateHeaderState(
7982
findFirstVisibleItemPosition(), getVisibleHeaders(), viewRetriever);
83+
if (viewHolder != null) {
84+
ZulipApp.get().getZulipActivity().setViewHolder(viewHolder);
85+
}
8086
}
8187
return scroll;
8288
}

app/src/main/java/com/zulip/android/viewholders/stickyheaders/interfaces/RetrieveHeaderView.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import android.support.v7.widget.RecyclerView;
55
import android.view.ViewGroup;
66

7+
import com.zulip.android.ZulipApp;
8+
79
public interface RetrieveHeaderView {
810

911
int DEFAULT_VIEW_TYPE = -1;
@@ -31,7 +33,7 @@ public RecyclerView.ViewHolder getViewHolderForPosition(int position) {
3133
}
3234
//set top margin for sticky header to 0 as in message_header.xml it is present which is only required when header is in between of messages
3335
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) currentViewHolder.itemView.getLayoutParams();
34-
layoutParams.setMargins(0,0,0,0);
36+
layoutParams.setMargins(0, ZulipApp.get().getZulipActivity().getFloatingHeaderTopMargin(), 0, 0);
3537
return currentViewHolder;
3638
}
3739
}

0 commit comments

Comments
 (0)