Translate FAB when scrolling between stopwatch page
This commit is contained in:
parent
7dfda796f3
commit
15afc01735
@ -1,6 +1,7 @@
|
|||||||
package com.philliphsu.clock2;
|
package com.philliphsu.clock2;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.support.design.widget.FloatingActionButton;
|
import android.support.design.widget.FloatingActionButton;
|
||||||
@ -57,12 +58,63 @@ public class MainActivity extends BaseActivity {
|
|||||||
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
|
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
|
||||||
mViewPager.setAdapter(mSectionsPagerAdapter);
|
mViewPager.setAdapter(mSectionsPagerAdapter);
|
||||||
mViewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
|
mViewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
|
||||||
|
/**
|
||||||
|
* @param position Either the current page position if the offset is increasing,
|
||||||
|
* or the previous page position if it is decreasing.
|
||||||
|
* @param positionOffset If increasing from [0, 1), scrolling right and position = currentPagePosition
|
||||||
|
* If decreasing from (1, 0], scrolling left and position = (currentPagePosition - 1)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||||
|
// Log.d(TAG, String.format("pos = %d, posOffset = %f, posOffsetPixels = %d",
|
||||||
|
// position, positionOffset, positionOffsetPixels));
|
||||||
|
int pageBeforeLast = mSectionsPagerAdapter.getCount() - 2;
|
||||||
|
if (position <= pageBeforeLast) {
|
||||||
|
if (position < pageBeforeLast) {
|
||||||
|
// When the scrolling is due to tab selection between multiple tabs apart,
|
||||||
|
// this callback is called for each intermediate page, but each of those pages
|
||||||
|
// will briefly register a sparsely decreasing range of positionOffsets, always
|
||||||
|
// from (1, 0). As such, you would notice the FAB to jump back and forth between
|
||||||
|
// x-positions as each intermediate page is scrolled through.
|
||||||
|
// This is a visual optimization that ends the translation motion, immediately
|
||||||
|
// returning the FAB to its target position.
|
||||||
|
mFab.setTranslationX(0);
|
||||||
|
} else {
|
||||||
|
// Initially, the FAB's translationX property is zero because, at its original
|
||||||
|
// position, it is not translated. setTranslationX() is relative to the view's
|
||||||
|
// left position, at its original position; this left position is taken to be
|
||||||
|
// the zero point of the coordinate system relative to this view. As your
|
||||||
|
// translationX value is increasingly negative, the view is translated left.
|
||||||
|
// But as translationX is decreasingly negative and down to zero, the view
|
||||||
|
// is translated right, back to its original position.
|
||||||
|
float translationX = positionOffsetPixels / -2f;
|
||||||
|
// NOTE: You MUST scale your own additional pixel offsets by positionOffset,
|
||||||
|
// or else the FAB will immediately translate by that many pixels, causing
|
||||||
|
// jitter as you scroll.
|
||||||
|
final int margin;
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
// Since each side's margin is the same, any side's would do.
|
||||||
|
margin = ((ViewGroup.MarginLayoutParams) mFab.getLayoutParams()).rightMargin;
|
||||||
|
} else {
|
||||||
|
// Pre-Lollipop has measurement issues with FAB margins. This is
|
||||||
|
// probably as good as we can get to centering the FAB, without
|
||||||
|
// hardcoding some small margin value.
|
||||||
|
margin = 0;
|
||||||
|
}
|
||||||
|
// Translation is done relative to a view's left position; by adding
|
||||||
|
// an offset of half the FAB's width, we effectively rebase the translation
|
||||||
|
// relative to the view's center position.
|
||||||
|
translationX += positionOffset * (mFab.getWidth() / 2f + margin);
|
||||||
|
mFab.setTranslationX(translationX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPageSelected(int position) {
|
public void onPageSelected(int position) {
|
||||||
if (position == mSectionsPagerAdapter.getCount() - 1) {
|
if (position < mSectionsPagerAdapter.getCount() - 1) {
|
||||||
mFab.hide();
|
// TODO: Plus icon. Consider caching the Drawable in a member variable.
|
||||||
} else {
|
mFab.setImageResource(android.R.drawable.ic_dialog_email);
|
||||||
mFab.show();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// @Override
|
// @Override
|
||||||
|
|||||||
@ -12,13 +12,14 @@ import android.util.Log;
|
|||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ImageButton;
|
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
|
|
||||||
import com.philliphsu.clock2.R;
|
import com.philliphsu.clock2.R;
|
||||||
import com.philliphsu.clock2.RecyclerViewFragment;
|
import com.philliphsu.clock2.RecyclerViewFragment;
|
||||||
import com.philliphsu.clock2.util.ProgressBarUtils;
|
import com.philliphsu.clock2.util.ProgressBarUtils;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
import butterknife.Bind;
|
import butterknife.Bind;
|
||||||
import butterknife.OnClick;
|
import butterknife.OnClick;
|
||||||
|
|
||||||
@ -43,11 +44,11 @@ public class StopwatchFragment extends RecyclerViewFragment<
|
|||||||
private AsyncLapsTableUpdateHandler mUpdateHandler;
|
private AsyncLapsTableUpdateHandler mUpdateHandler;
|
||||||
private ObjectAnimator mProgressAnimator;
|
private ObjectAnimator mProgressAnimator;
|
||||||
private SharedPreferences mPrefs;
|
private SharedPreferences mPrefs;
|
||||||
|
private WeakReference<FloatingActionButton> mActivityFab;
|
||||||
|
|
||||||
@Bind(R.id.chronometer) ChronometerWithMillis mChronometer;
|
@Bind(R.id.chronometer) ChronometerWithMillis mChronometer;
|
||||||
@Bind(R.id.new_lap) ImageButton mNewLapButton;
|
@Bind(R.id.new_lap) FloatingActionButton mNewLapButton;
|
||||||
@Bind(R.id.fab) FloatingActionButton mFab;
|
@Bind(R.id.stop) FloatingActionButton mStopButton;
|
||||||
@Bind(R.id.stop) ImageButton mStopButton;
|
|
||||||
@Bind(R.id.progress_bar) ProgressBar mProgressBar;
|
@Bind(R.id.progress_bar) ProgressBar mProgressBar;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -62,6 +63,8 @@ public class StopwatchFragment extends RecyclerViewFragment<
|
|||||||
mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
|
mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
|
||||||
mStartTime = mPrefs.getLong(KEY_START_TIME, 0);
|
mStartTime = mPrefs.getLong(KEY_START_TIME, 0);
|
||||||
mPauseTime = mPrefs.getLong(KEY_PAUSE_TIME, 0);
|
mPauseTime = mPrefs.getLong(KEY_PAUSE_TIME, 0);
|
||||||
|
// TODO: Any better solutions?
|
||||||
|
mActivityFab = new WeakReference<>((FloatingActionButton) getActivity().findViewById(R.id.fab));
|
||||||
Log.d(TAG, "mStartTime = " + mStartTime
|
Log.d(TAG, "mStartTime = " + mStartTime
|
||||||
+ ", mPauseTime = " + mPauseTime);
|
+ ", mPauseTime = " + mPauseTime);
|
||||||
}
|
}
|
||||||
@ -82,6 +85,8 @@ public class StopwatchFragment extends RecyclerViewFragment<
|
|||||||
if (mPrefs.getBoolean(KEY_CHRONOMETER_RUNNING, false)) {
|
if (mPrefs.getBoolean(KEY_CHRONOMETER_RUNNING, false)) {
|
||||||
mChronometer.start();
|
mChronometer.start();
|
||||||
}
|
}
|
||||||
|
// Hides the mini fabs prematurely, so when we actually select this tab
|
||||||
|
// they don't show at all before hiding.
|
||||||
updateButtonControls();
|
updateButtonControls();
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
@ -138,45 +143,8 @@ public class StopwatchFragment extends RecyclerViewFragment<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
@Override
|
||||||
protected LapsAdapter getAdapter() {
|
public void onFabClick() {
|
||||||
if (super.getAdapter() != null)
|
|
||||||
return super.getAdapter();
|
|
||||||
return new LapsAdapter();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int contentLayout() {
|
|
||||||
return R.layout.fragment_stopwatch;
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnClick(R.id.new_lap)
|
|
||||||
void addNewLap() {
|
|
||||||
if (!mChronometer.isRunning()) {
|
|
||||||
Log.d(TAG, "Cannot add new lap");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (mCurrentLap != null) {
|
|
||||||
mCurrentLap.end(mChronometer.getText().toString());
|
|
||||||
}
|
|
||||||
mPreviousLap = mCurrentLap;
|
|
||||||
mCurrentLap = new Lap();
|
|
||||||
if (mPreviousLap != null) {
|
|
||||||
// if (getAdapter().getItemCount() == 0) {
|
|
||||||
// mUpdateHandler.asyncInsert(mPreviousLap);
|
|
||||||
// } else {
|
|
||||||
mUpdateHandler.asyncUpdate(mPreviousLap.getId(), mPreviousLap);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
mUpdateHandler.asyncInsert(mCurrentLap);
|
|
||||||
// This would end up being called twice: here, and in onLoadFinished(), because the
|
|
||||||
// table updates will prompt us to requery.
|
|
||||||
// startNewProgressBarAnimator();
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnClick(R.id.fab)
|
|
||||||
void startPause() {
|
|
||||||
if (mChronometer.isRunning()) {
|
if (mChronometer.isRunning()) {
|
||||||
mPauseTime = SystemClock.elapsedRealtime();
|
mPauseTime = SystemClock.elapsedRealtime();
|
||||||
mChronometer.stop();
|
mChronometer.stop();
|
||||||
@ -221,6 +189,65 @@ public class StopwatchFragment extends RecyclerViewFragment<
|
|||||||
savePrefs();
|
savePrefs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setUserVisibleHint(boolean isVisibleToUser) {
|
||||||
|
super.setUserVisibleHint(isVisibleToUser);
|
||||||
|
// We get called multiple times, even when we're not yet visible.
|
||||||
|
// This can be called before onCreateView() so widgets could be null, esp. if you had
|
||||||
|
// navigated more than one page away before returning here. That means onDestroyView()
|
||||||
|
// was called previously.
|
||||||
|
// We will get called again when we actually have this page selected, and by that time
|
||||||
|
// onCreateView() will have been called. Wait until we're resumed to call through.
|
||||||
|
if (isVisibleToUser && isResumed()) {
|
||||||
|
// At this point, the only thing this does is change the fab icon
|
||||||
|
// TODO: allow duplicate code and manipulate the fab icon directly?
|
||||||
|
// TODO: There is noticeable latency between showing this tab and
|
||||||
|
// changing the icon. Consider writing a callback for this Fragment
|
||||||
|
// that MainActivity can call in its onPageChangeListener. We don't merely
|
||||||
|
// want to call such a callback in onPageSelected, because that is fired
|
||||||
|
// when we reach an idle state, so we'd experience the same latency issue.
|
||||||
|
// Rather, we should animate the icon change during onPageScrolled.
|
||||||
|
updateButtonControls();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
protected LapsAdapter getAdapter() {
|
||||||
|
if (super.getAdapter() != null)
|
||||||
|
return super.getAdapter();
|
||||||
|
return new LapsAdapter();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int contentLayout() {
|
||||||
|
return R.layout.fragment_stopwatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnClick(R.id.new_lap)
|
||||||
|
void addNewLap() {
|
||||||
|
if (!mChronometer.isRunning()) {
|
||||||
|
Log.d(TAG, "Cannot add new lap");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mCurrentLap != null) {
|
||||||
|
mCurrentLap.end(mChronometer.getText().toString());
|
||||||
|
}
|
||||||
|
mPreviousLap = mCurrentLap;
|
||||||
|
mCurrentLap = new Lap();
|
||||||
|
if (mPreviousLap != null) {
|
||||||
|
// if (getAdapter().getItemCount() == 0) {
|
||||||
|
// mUpdateHandler.asyncInsert(mPreviousLap);
|
||||||
|
// } else {
|
||||||
|
mUpdateHandler.asyncUpdate(mPreviousLap.getId(), mPreviousLap);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
mUpdateHandler.asyncInsert(mCurrentLap);
|
||||||
|
// This would end up being called twice: here, and in onLoadFinished(), because the
|
||||||
|
// table updates will prompt us to requery.
|
||||||
|
// startNewProgressBarAnimator();
|
||||||
|
}
|
||||||
|
|
||||||
@OnClick(R.id.stop)
|
@OnClick(R.id.stop)
|
||||||
void stop() {
|
void stop() {
|
||||||
mChronometer.stop();
|
mChronometer.stop();
|
||||||
@ -246,8 +273,10 @@ public class StopwatchFragment extends RecyclerViewFragment<
|
|||||||
int vis = started ? View.VISIBLE : View.INVISIBLE;
|
int vis = started ? View.VISIBLE : View.INVISIBLE;
|
||||||
mNewLapButton.setVisibility(vis);
|
mNewLapButton.setVisibility(vis);
|
||||||
mStopButton.setVisibility(vis);
|
mStopButton.setVisibility(vis);
|
||||||
// TODO: pause and start icon, resp.
|
if (isVisible()) { // avoid changing the icon prematurely, esp. when we're not on this tab
|
||||||
mFab.setImageResource(mChronometer.isRunning() ? 0 : 0);
|
// TODO: pause and start icon, resp.
|
||||||
|
mActivityFab.get().setImageResource(mChronometer.isRunning() ? 0 : 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startNewProgressBarAnimator() {
|
private void startNewProgressBarAnimator() {
|
||||||
@ -273,11 +302,6 @@ public class StopwatchFragment extends RecyclerViewFragment<
|
|||||||
|
|
||||||
// ======================= DO NOT IMPLEMENT ============================
|
// ======================= DO NOT IMPLEMENT ============================
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFabClick() {
|
|
||||||
// DO NOT THROW AN UNSUPPORTED OPERATION EXCEPTION.
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onScrolledToStableId(long id, int position) {
|
protected void onScrolledToStableId(long id, int position) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
|
|||||||
@ -1,69 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<android.support.design.widget.CoordinatorLayout
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:id="@+id/top_panel"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@color/colorPrimary"
|
|
||||||
android:padding="16dp">
|
|
||||||
|
|
||||||
<com.philliphsu.clock2.stopwatch.ChronometerWithMillis
|
|
||||||
android:id="@+id/chronometer"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_centerHorizontal="true"
|
|
||||||
android:textSize="45sp"
|
|
||||||
style="@style/TextAppearance.AppCompat.Inverse"
|
|
||||||
android:layout_marginBottom="16dp"/>
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/new_lap"
|
|
||||||
android:layout_width="56dp"
|
|
||||||
android:layout_height="56dp"
|
|
||||||
android:background="?selectableItemBackground"
|
|
||||||
android:layout_below="@id/chronometer"
|
|
||||||
android:layout_alignParentStart="true"
|
|
||||||
android:src="@drawable/ic_half_day_1_black_24dp"/>
|
|
||||||
|
|
||||||
<android.support.design.widget.FloatingActionButton
|
|
||||||
android:id="@+id/fab"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_below="@id/chronometer"
|
|
||||||
android:layout_centerInParent="true"/>
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/stop"
|
|
||||||
android:layout_width="56dp"
|
|
||||||
android:layout_height="56dp"
|
|
||||||
android:background="?selectableItemBackground"
|
|
||||||
android:layout_below="@id/chronometer"
|
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:src="@drawable/ic_half_day_1_black_24dp"/>
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
<!-- RecyclerView -->
|
|
||||||
<include layout="@layout/fragment_recycler_view"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<ProgressBar
|
|
||||||
android:id="@+id/progress_bar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:layout_anchor="@id/top_panel"
|
|
||||||
app:layout_anchorGravity="bottom"
|
|
||||||
style="@style/Widget.AppCompat.ProgressBar.Horizontal"/>
|
|
||||||
|
|
||||||
</android.support.design.widget.CoordinatorLayout>
|
|
||||||
@ -43,7 +43,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="bottom|end"
|
android:layout_gravity="bottom|end"
|
||||||
android:layout_margin="@dimen/fab_margin"
|
android:src="@android:drawable/ic_dialog_email"
|
||||||
android:src="@android:drawable/ic_dialog_email"/>
|
android:layout_margin="@dimen/fab_margin"/>
|
||||||
|
|
||||||
</android.support.design.widget.CoordinatorLayout>
|
</android.support.design.widget.CoordinatorLayout>
|
||||||
|
|||||||
@ -10,53 +10,15 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<LinearLayout
|
<com.philliphsu.clock2.stopwatch.ChronometerWithMillis
|
||||||
android:id="@+id/top_panel"
|
android:id="@+id/chronometer"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:padding="16dp"
|
||||||
android:background="@color/colorPrimary"
|
android:background="@color/colorPrimary"
|
||||||
android:padding="16dp">
|
android:gravity="center_horizontal"
|
||||||
|
android:textSize="@dimen/text_size_display_3"
|
||||||
<com.philliphsu.clock2.stopwatch.ChronometerWithMillis
|
style="@style/TextAppearance.AppCompat.Inverse"/>
|
||||||
android:id="@+id/chronometer"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_horizontal"
|
|
||||||
android:textSize="45sp"
|
|
||||||
style="@style/TextAppearance.AppCompat.Inverse"/>
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/new_lap"
|
|
||||||
android:layout_width="56dp"
|
|
||||||
android:layout_height="56dp"
|
|
||||||
android:background="?selectableItemBackground"
|
|
||||||
android:layout_alignParentStart="true"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:src="@drawable/ic_half_day_1_black_24dp"/>
|
|
||||||
|
|
||||||
<android.support.design.widget.FloatingActionButton
|
|
||||||
android:id="@+id/fab"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_centerInParent="true"/>
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/stop"
|
|
||||||
android:layout_width="56dp"
|
|
||||||
android:layout_height="56dp"
|
|
||||||
android:background="?selectableItemBackground"
|
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:src="@drawable/ic_half_day_1_black_24dp"/>
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<!-- RecyclerView -->
|
<!-- RecyclerView -->
|
||||||
<include layout="@layout/fragment_recycler_view"/>
|
<include layout="@layout/fragment_recycler_view"/>
|
||||||
@ -67,8 +29,39 @@
|
|||||||
android:id="@+id/progress_bar"
|
android:id="@+id/progress_bar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_anchor="@id/top_panel"
|
app:layout_anchor="@id/chronometer"
|
||||||
app:layout_anchorGravity="bottom"
|
app:layout_anchorGravity="bottom"
|
||||||
style="@style/Widget.AppCompat.ProgressBar.Horizontal"/>
|
style="@style/Widget.AppCompat.ProgressBar.Horizontal"/>
|
||||||
|
|
||||||
|
<!-- TODO: dimen resource for height -->
|
||||||
|
<android.support.v7.widget.GridLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="88dp"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
app:columnCount="2">
|
||||||
|
|
||||||
|
<android.support.design.widget.FloatingActionButton
|
||||||
|
android:id="@+id/new_lap"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:src="@drawable/ic_half_day_1_black_24dp"
|
||||||
|
android:tint="@android:color/darker_gray"
|
||||||
|
app:layout_columnWeight="1"
|
||||||
|
app:layout_gravity="center"
|
||||||
|
app:fabSize="mini"
|
||||||
|
app:backgroundTint="@android:color/white"/>
|
||||||
|
|
||||||
|
<android.support.design.widget.FloatingActionButton
|
||||||
|
android:id="@+id/stop"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:src="@drawable/ic_half_day_1_black_24dp"
|
||||||
|
android:tint="@android:color/darker_gray"
|
||||||
|
app:layout_columnWeight="1"
|
||||||
|
app:layout_gravity="center"
|
||||||
|
app:fabSize="mini"
|
||||||
|
app:backgroundTint="@android:color/white"/>
|
||||||
|
|
||||||
|
</android.support.v7.widget.GridLayout>
|
||||||
|
|
||||||
</android.support.design.widget.CoordinatorLayout>
|
</android.support.design.widget.CoordinatorLayout>
|
||||||
Loading…
Reference in New Issue
Block a user