Skip to content

Commit

Permalink
Merge pull request #14 from DroidKaigi/master
Browse files Browse the repository at this point in the history
update
  • Loading branch information
Keita Watanabe authored Feb 19, 2017
2 parents 3a29901 + b919ee4 commit eaa96d7
Show file tree
Hide file tree
Showing 11 changed files with 221 additions and 30 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,8 @@ public class Speaker {
## ViewModel
- In `viewmodel` package
- "ViewModel" has all properties which is shown in "View".
- They are bind by DataBinding. In this app, `setText()` or `setImageResource()`, `setVisibility()` are not used.
- The events such as `OnClickListener()` are also bind by DataBinding.
- They are bound by DataBinding. In this app, `setText()`, `setImageResource()` or `setVisibility()` are not used.
- The events such as `OnClickListener()` are also bound by DataBinding.

```xml
<RelativeLayout
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
android:exported="false"
android:label="@string/session_detail"
android:parentActivityName=".view.activity.MainActivity"
android:theme="@style/AppTheme.NoActionBar"
android:theme="@style/AppTheme.Translucent.Half"
/>

<activity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,7 @@
import android.content.Context;
import android.content.Intent;
import android.databinding.DataBindingUtil;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;

import javax.inject.Inject;

Expand Down Expand Up @@ -39,23 +35,4 @@ protected void onCreate(Bundle savedInstanceState) {
viewModel.setToolbarTitle(getString(R.string.contributors));
replaceFragment(ContributorsFragment.newInstance(), R.id.content_view);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_contributors, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.item_repository:
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/DroidKaigi/conference-app-2017"));
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
package io.github.droidkaigi.confsched2017.view.customview;

import android.animation.Animator;
import android.content.Context;
import android.databinding.BindingMethod;
import android.databinding.BindingMethods;
import android.graphics.PointF;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.CoordinatorLayout;
import android.support.v4.widget.NestedScrollView;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;

import io.github.droidkaigi.confsched2017.R;


@BindingMethods({
@BindingMethod(type = OverScrollLayout.class, attribute = "onOverScroll", method = "setOverScrollListener")
})
public class OverScrollLayout extends CoordinatorLayout {

private static final float OVER_SCROLL_THRESHOLD = 0.20f;

private static final int RESTORE_ANIM_DURATION = 100;

private static final float MINIMUM_OVER_SCROLL_SCALE = 0.99f;

private int overScrollThreshold;

private PointF originalLocation = new PointF();

private int originalHeight;

private OnOverScrollListener overScrollListener;

public OverScrollLayout(Context context) {
super(context);
}

public OverScrollLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}

public OverScrollLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
originalLocation.set(left, top);
originalHeight = bottom - top;
overScrollThreshold = (int) (originalHeight * OVER_SCROLL_THRESHOLD);
}

@Override
public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {
if (getY() != originalLocation.y) {
float scale =
Math.max(MINIMUM_OVER_SCROLL_SCALE,
1 - (Math.abs(getY()) / overScrollThreshold) * (1 - MINIMUM_OVER_SCROLL_SCALE));
setScaleX(scale);
setScaleY(scale);
translationY(-dy);
consumed[1] = dy;
} else {
super.onNestedPreScroll(target, dx, dy, consumed);
}
}

@Override
public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
super.onNestedScroll(target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
AppBarLayout appBarLayout = null;
boolean scrollTop = false;
boolean scrollEnd = false;
for (int i = 0; i < getChildCount(); i++) {
View view = getChildAt(i);
if (view instanceof AppBarLayout) {
appBarLayout = (AppBarLayout) view;
continue;
}
if (view instanceof NestedScrollView) {
scrollTop = !view.canScrollVertically(-1);
scrollEnd = !view.canScrollVertically(1);
}
}

if (appBarLayout == null || scrollTop && dyUnconsumed < 0 && isAppBarExpanded(appBarLayout)) {
translationY(-dyUnconsumed);
}
if (appBarLayout == null || scrollEnd && dyUnconsumed > 0 && isAppBarCollapsed(appBarLayout)) {
translationY(-dyUnconsumed);
}
}

@Override
public boolean onNestedPreFling(View target, float velocityX, float velocityY) {
return getY() != originalLocation.y || super.onNestedPreFling(target, velocityX, velocityY);
}

@Override
public void onStopNestedScroll(View target) {
super.onStopNestedScroll(target);
if (Math.abs(getY()) > overScrollThreshold && overScrollListener != null) {
float yTranslation;
if (getY() > 0) {
yTranslation = originalLocation.y + originalHeight;
} else {
yTranslation = originalLocation.y - originalHeight;
}
animate()
.setDuration(getContext().getResources().getInteger(R.integer.activity_transition_mills))
.setInterpolator(new AccelerateDecelerateInterpolator())
.alpha(0)
.translationY(yTranslation)
.setListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}

@Override
public void onAnimationEnd(Animator animation) {
overScrollListener.onOverScroll();

}

@Override
public void onAnimationCancel(Animator animation) {
}

@Override
public void onAnimationRepeat(Animator animation) {
}
});
return;
}
if (getY() != originalLocation.y) {
animate()
.setDuration(RESTORE_ANIM_DURATION)
.setInterpolator(new AccelerateDecelerateInterpolator())
.translationY(originalLocation.y)
.scaleX(1)
.scaleY(1);
}
}

private void translationY(float dy) {
setY(getY() + dy * 0.5f);
}

private boolean isAppBarExpanded(@NonNull AppBarLayout appBarLayout) {
return appBarLayout.getHeight() == appBarLayout.getBottom();
}

private boolean isAppBarCollapsed(@NonNull AppBarLayout appBarLayout) {
return Math.abs(appBarLayout.getY()) == appBarLayout.getTotalScrollRange();
}

public void setOverScrollListener(@Nullable OnOverScrollListener listener) {
this.overScrollListener = listener;
}

public interface OnOverScrollListener {

void onOverScroll();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.GridLayoutManager;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;

Expand Down Expand Up @@ -58,13 +61,30 @@ public void onCreate(@Nullable Bundle savedInstanceState) {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
setHasOptionsMenu(true);
binding = FragmentContributorsBinding.inflate(inflater, container, false);
binding.setViewModel(viewModel);

initView();
return binding.getRoot();
}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) {
menuInflater.inflate(R.menu.menu_contributors, menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.item_repository:
viewModel.onClickRepositoryMenu();
return true;
default:
return super.onOptionsItemSelected(item);
}
}

@Override
public void onStop() {
super.onStop();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@

import io.github.droidkaigi.confsched2017.R;
import io.github.droidkaigi.confsched2017.databinding.FragmentSessionDetailBinding;
import io.github.droidkaigi.confsched2017.view.activity.SessionFeedbackActivity;
import io.github.droidkaigi.confsched2017.view.helper.AnimationHelper;
import io.github.droidkaigi.confsched2017.viewmodel.SessionDetailViewModel;
import io.reactivex.android.schedulers.AndroidSchedulers;
Expand Down Expand Up @@ -170,4 +169,10 @@ public void onClickFab(boolean selected) {
.setActionTextColor(actionTextColor)
.show();
}

@Override
public void onOverScroll() {
getActivity().finish();
getActivity().overridePendingTransition(0, 0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ public ObservableList<ContributorViewModel> getContributorViewModels() {
return this.viewModels;
}

public void onClickRepositoryMenu(){
navigator.navigateToWebPage("https://github.com/DroidKaigi/conference-app-2017");
}

private void loadContributors(boolean refresh) {
if (refresh) {
contributorsRepository.setDirty(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ public void onClickFab(@SuppressWarnings("unused") View view) {
}
}

public void onOverScroll() {
callback.onOverScroll();
}

private String decideSessionTimeRange(Context context, Session session) {
Date displaySTime = LocaleUtil.getDisplayDate(session.stime, context);
Date displayETime = LocaleUtil.getDisplayDate(session.etime, context);
Expand Down Expand Up @@ -218,5 +222,7 @@ public void setCallback(Callback callback) {
public interface Callback {

void onClickFab(boolean selected);

void onOverScroll();
}
}
7 changes: 4 additions & 3 deletions app/src/main/res/layout/fragment_session_detail.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@
/>
</data>

<android.support.design.widget.CoordinatorLayout
<io.github.droidkaigi.confsched2017.view.customview.OverScrollLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:onOverScroll="@{viewModel::onOverScroll}"
>

<android.support.design.widget.AppBarLayout
Expand Down Expand Up @@ -77,10 +78,10 @@

<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
style="@style/BaseToolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/selectableItemBackground"
style="@style/BaseToolbar"
app:layout_collapseMode="pin"
/>

Expand Down Expand Up @@ -302,6 +303,6 @@
app:topicVividColor="@{viewModel.sessionVividColorResId}"
/>

</android.support.design.widget.CoordinatorLayout>
</io.github.droidkaigi.confsched2017.view.customview.OverScrollLayout>

</layout>
2 changes: 2 additions & 0 deletions app/src/main/res/values-ja/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
<string name="description">内容</string>
<string name="slide_and_video">資料&動画</string>
<string name="send_feedback">フィードバックを送る</string>
<!-- My Sessions -->
<string name="my_session_empty">まだセッションが登録されていません。セッションリストを確認し、気になるセッションをチェックアウトしましょう!</string>
<!-- Settings -->
<string name="settings_language">言語を設定</string>
<string name="settings_language_description">表示言語を変更できます。変更後はアプリが再起動されます。</string>
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/res/values/themes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@
<item name="windowActionBar">false</item>
</style>

<style name="AppTheme.Translucent.Half">
<item name="android:windowBackground">@color/black_alpha_54</item>
</style>


<style name="DialogTheme" parent="Theme.AppCompat.Light.Dialog">
<item name="colorAccent">@color/theme</item>
</style>
Expand Down

0 comments on commit eaa96d7

Please sign in to comment.