Created ScrollingGridTimePickerDialog

This commit is contained in:
Phillip Hsu 2016-07-17 03:02:57 -07:00
parent d1c0820de4
commit bc2446d586
9 changed files with 229 additions and 14 deletions

View File

@ -1,12 +1,23 @@
package com.philliphsu.clock2.editalarm; package com.philliphsu.clock2.editalarm;
import android.os.Bundle;
import android.support.annotation.LayoutRes;
import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment; import android.support.v4.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import butterknife.ButterKnife;
/** /**
* Created by Phillip Hsu on 7/16/2016. * Created by Phillip Hsu on 7/16/2016.
*/ */
public abstract class BaseTimePickerDialog extends DialogFragment { public abstract class BaseTimePickerDialog extends DialogFragment {
// TODO: Consider private access, and then writing package/protected API that subclasses
// can use to interface with this field.
/*package*/ TimePicker.OnTimeSetListener mCallback; /*package*/ TimePicker.OnTimeSetListener mCallback;
/** /**
@ -15,7 +26,25 @@ public abstract class BaseTimePickerDialog extends DialogFragment {
*/ */
public BaseTimePickerDialog() {} public BaseTimePickerDialog() {}
@LayoutRes
protected abstract int contentLayout();
public final void setOnTimeSetListener(TimePicker.OnTimeSetListener callback) { public final void setOnTimeSetListener(TimePicker.OnTimeSetListener callback) {
mCallback = callback; mCallback = callback;
} }
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
View view = inflater.inflate(contentLayout(), container, false);
ButterKnife.bind(this, view);
return view;
}
@Override
public void onDestroyView() {
super.onDestroyView();
ButterKnife.unbind(this);
}
} }

View File

@ -317,8 +317,9 @@ public class EditAlarmActivity extends BaseActivity implements
// If we keep a reference to the dialog, we keep its previous state as well. // If we keep a reference to the dialog, we keep its previous state as well.
// So the next time we call show() on it, the input field will show the // So the next time we call show() on it, the input field will show the
// last inputted time. // last inputted time.
NumpadTimePickerDialog.newInstance(EditAlarmActivity.this) /*NumpadTimePickerDialog.newInstance(EditAlarmActivity.this)
.show(getSupportFragmentManager(), TAG_TIME_PICKER); .show(getSupportFragmentManager(), TAG_TIME_PICKER);*/
ScrollingGridTimePickerDialog.newInstance(this, true).show(getSupportFragmentManager(), "tag");
} }
private void setWeekDaysText() { private void setWeekDaysText() {

View File

@ -4,13 +4,11 @@ import android.os.Bundle;
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.view.Window;
import android.widget.EditText; import android.widget.EditText;
import com.philliphsu.clock2.R; import com.philliphsu.clock2.R;
import butterknife.Bind; import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick; import butterknife.OnClick;
import butterknife.OnTouch; import butterknife.OnTouch;
@ -81,11 +79,7 @@ public class NumpadTimePickerDialog extends BaseTimePickerDialog
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE); View view = super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.dialog_time_picker_numpad, container, false);
ButterKnife.bind(this, view);
// Can't do a method bind because the FAB is not part of this dialog's layout // Can't do a method bind because the FAB is not part of this dialog's layout
// Also can't do the bind in the Numpad's class, because it doesn't have access to // Also can't do the bind in the Numpad's class, because it doesn't have access to
// the OnTimeSetListener callback contained here or the dialog's dismiss() // the OnTimeSetListener callback contained here or the dialog's dismiss()
@ -108,6 +102,11 @@ public class NumpadTimePickerDialog extends BaseTimePickerDialog
return view; return view;
} }
@Override
protected int contentLayout() {
return R.layout.dialog_time_picker_numpad;
}
@Override @Override
public void onSaveInstanceState(Bundle outState) { public void onSaveInstanceState(Bundle outState) {
if (mNumpad != null) { if (mNumpad != null) {

View File

@ -0,0 +1,54 @@
package com.philliphsu.clock2.editalarm;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.philliphsu.clock2.R;
/**
* Created by Phillip Hsu on 7/17/2016.
*/
public class ScrollingGridAdapter extends RecyclerView.Adapter<ScrollingGridAdapter.ViewHolder> {
private String[] mValues;
private View.OnClickListener mOnClickListener;
/**
* @param values the values to display
* @param listener a click listener so clients can be notified of when the View corresponding
* to a value was clicked, so they may call notifyDataSetChanged() if need be
*/
public ScrollingGridAdapter(String[] values, View.OnClickListener listener) {
mValues = values;
mOnClickListener = listener;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_scrolling_grid_value, parent, false);
return new ViewHolder(view, mOnClickListener);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
TextView tv = (TextView) holder.itemView;
tv.setText(mValues[position]);
}
@Override
public int getItemCount() {
return mValues == null ? 0 : mValues.length;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(View itemView, View.OnClickListener listener) {
super(itemView);
itemView.setOnClickListener(listener);
}
}
}

View File

@ -1,16 +1,69 @@
package com.philliphsu.clock2.editalarm; package com.philliphsu.clock2.editalarm;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.philliphsu.clock2.R;
import butterknife.Bind;
/** /**
* Created by Phillip Hsu on 7/16/2016. * Created by Phillip Hsu on 7/16/2016.
*/ */
public class ScrollingGridTimePickerDialog extends BaseTimePickerDialog { public class ScrollingGridTimePickerDialog extends BaseTimePickerDialog {
private static final int COLUMNS = 3;
private TimePicker.OnTimeSetListener mCallback; private ScrollingGridAdapter mAdapter;
private String[] mValues;
private boolean mIs24HourMode;
public static NumpadTimePickerDialog newInstance(TimePicker.OnTimeSetListener callback) { @Bind(R.id.grid) RecyclerView mGrid;
NumpadTimePickerDialog ret = new NumpadTimePickerDialog();
public static ScrollingGridTimePickerDialog newInstance(TimePicker.OnTimeSetListener callback, boolean is24HourMode) {
ScrollingGridTimePickerDialog ret = new ScrollingGridTimePickerDialog();
ret.setOnTimeSetListener(callback); ret.setOnTimeSetListener(callback);
ret.initialize(is24HourMode);
return ret; return ret;
} }
public void initialize(boolean is24HourMode) {
mIs24HourMode = is24HourMode;
if (mIs24HourMode) {
mValues = new String[] {
"00", "01", "02", "03", "04", "05", "06", "07",
"08", "09", "10", "11", "12", "13", "14", "15",
"16", "17", "18", "19", "20", "21", "22", "23"};
} else {
mValues = new String[] {
"1", "2", "3", "4", "5", "6",
"7", "8", "9", "10", "11", "12"};
}
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = super.onCreateView(inflater, container, savedInstanceState);
mGrid.setLayoutManager(new GridLayoutManager(view.getContext(), COLUMNS));
mAdapter = new ScrollingGridAdapter(mValues, new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO: If on hours, switch dataset to minutes values. Else, do nothing.
mAdapter.notifyDataSetChanged();
}
});
mGrid.setAdapter(mAdapter);
return view;
}
@Override
protected int contentLayout() {
return R.layout.dialog_time_picker_scrolling_grid;
}
} }

View File

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- TOneverDO: Use LinearLayout because it doesn't obey LWM -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/grid"
android:layout_width="match_parent"
android:layout_height="@dimen/scrolling_grid_height"
android:scrollbars="vertical"
android:scrollbarSize="@dimen/scrollbar_width"
android:fadeScrollbars="false"
android:layout_alignParentTop="true"/>
<View
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?android:listDividerAlertDialog"
android:layout_below="@id/grid"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/fab_cell_height"
android:orientation="horizontal"
android:layout_below="@id/divider">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:minHeight="40dp"
android:layout_weight="1"
android:layout_gravity="center"
android:gravity="center"
android:text="AM"
android:textSize="@dimen/ampm_text_size"/>
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_done_24dp"/>
</FrameLayout>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:minHeight="40dp"
android:layout_weight="1"
android:layout_gravity="center"
android:gravity="center"
android:text="PM"
android:textSize="@dimen/ampm_text_size"/>
</LinearLayout>
</RelativeLayout>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="40dp"
android:textSize="@dimen/grid_element_text_size"
android:gravity="center"
android:layout_gravity="center"/>

View File

@ -11,11 +11,18 @@
<dimen name="alarm_time_text_size">48sp</dimen> <dimen name="alarm_time_text_size">48sp</dimen>
<dimen name="app_bar_height">180dp</dimen> <dimen name="app_bar_height">180dp</dimen>
<dimen name="text_margin">16dp</dimen> <dimen name="text_margin">16dp</dimen>
<dimen name="grid_element_text_size">28sp</dimen>
<!-- NumpadTimePickerDialog --> <!-- NumpadTimePickerDialog -->
<dimen name="header_height">72dp</dimen> <dimen name="header_height">72dp</dimen>
<dimen name="numpad_height">300dp</dimen> <dimen name="numpad_height">300dp</dimen>
<dimen name="time_input_text_size">45sp</dimen> <dimen name="time_input_text_size">45sp</dimen>
<dimen name="cancel_icon_size">56dp</dimen> <dimen name="cancel_icon_size">56dp</dimen>
<dimen name="fab_cell_height">88dp</dimen> <!-- 56dp fab size + 16dp top margin + 16dp bottom margin --> <dimen name="fab_cell_height">88dp</dimen> <!-- 56dp fab size + 16dp top margin + 16dp bottom margin -->
<!-- ScrollingGridTimePickerDialog -->
<dimen name="scrolling_grid_height">270dp</dimen>
<dimen name="scrollbar_width">10dp</dimen>
<dimen name="ampm_text_size">24sp</dimen>
</resources> </resources>

View File

@ -25,7 +25,7 @@
<item name="android:layout_width">0dp</item> <item name="android:layout_width">0dp</item>
<item name="android:layout_height">0dp</item> <item name="android:layout_height">0dp</item>
<item name="android:background">?android:attr/selectableItemBackground</item> <item name="android:background">?android:attr/selectableItemBackground</item>
<item name="android:textSize">28sp</item> <item name="android:textSize">@dimen/grid_element_text_size</item>
</style> </style>
</resources> </resources>