Skip to content

Commit

Permalink
Merge pull request #14 from DroidKaigi/master
Browse files Browse the repository at this point in the history
update
Keita Watanabe authored Feb 19, 2017

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
2 parents 3a29901 + b919ee4 commit eaa96d7
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
@@ -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
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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;

@@ -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
@@ -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;

@@ -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();
Original file line number Diff line number Diff line change
@@ -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;
@@ -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
@@ -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);
Original file line number Diff line number Diff line change
@@ -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);
@@ -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
@@ -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
@@ -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"
/>

@@ -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
@@ -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>
5 changes: 5 additions & 0 deletions app/src/main/res/values/themes.xml
Original file line number Diff line number Diff line change
@@ -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>

0 comments on commit eaa96d7

Please sign in to comment.