/*
* Copyright (C) 2011 Daniel Berndt - Codeus Ltd - DateSlider
*
* This class contains all the scrolling logic of the slidable elements
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.googlecode.android.widgets.DateSlider;
import java.lang.reflect.Constructor;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.Scroller;
import com.googlecode.android.widgets.DateSlider.labeler.Labeler;
import com.googlecode.android.widgets.DateSlider.timeview.TimeView;
/**
* This is where most of the magic happens. This is a subclass of LinearLayout
* that display a collection of TimeViews and handles the scrolling, shuffling
* the TimeViews around to keep the display up-to-date, and managing the Labelers
* to populate the TimeViews with the correct data.
*
* This class is configured via xml attributes that specify the class of the
* labeler to use to generate views, the format string for the labeler to use
* to populate the views, and optionally width and height values to override
* the default width and height of the views.
*/
public class ScrollLayout extends LinearLayout {
private static String TAG = "SCROLLLAYOUT";
private Scroller mScroller;
/**
* Indicates if we are currently tracking touch events that are dragging
* (scrolling) us.
*/
private boolean mDragMode;
/**
* The aggregate width of all of our children
*/
private int childrenWidth;
/**
* The aggregate width of our children is very likely to be wider than the
* bounds of our view. Since we keep everything centered, we need to keep
* our view scrolled by enough to center our children, rather than
* left-aligning them. This variable tracks how much to scroll to achieve this.
*/
private int mInitialOffset;
private int mLastX, mLastScroll, mScrollX;
private VelocityTracker mVelocityTracker;
private int mMinimumVelocity, mMaximumVelocity;
/**
* The time that we are currently displaying
*/
private long currentTime = System.currentTimeMillis();
private long minTime = -1, maxTime = -1;
private int minuteInterval = 1;
/**
* The width of each child
*/
private int objWidth;
/**
* The height of each child
*/
private int objHeight;
private Drawable rightShadow, leftShadow;
private Labeler mLabeler;
private OnScrollListener listener;
private TimeView mCenterView;
public ScrollLayout(Context context, AttributeSet attrs) {
super(context, attrs);
this.setWillNotDraw(false);
rightShadow = getContext().getResources().getDrawable(R.drawable.right_shadow);
leftShadow = getContext().getResources().getDrawable(R.drawable.left_shadow);
mScroller = new Scroller(getContext());
setGravity(Gravity.CENTER_VERTICAL);
setOrientation(HORIZONTAL);
final ViewConfiguration configuration = ViewConfiguration.get(getContext());
mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
// as mMaximumVelocity does not exist in API<4
float density = getContext().getResources().getDisplayMetrics().density;
mMaximumVelocity = (int)(4000 * 0.5f * density);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ScrollLayout,
0, 0);
// Get the labeler class and construct an instance
String className = a.getNonResourceString(R.styleable.ScrollLayout_labelerClass);
if (className == null) {
throw new RuntimeException("Must specify labeler class at " + a.getPositionDescription());
}
String labelerFormat = a.getString(R.styleable.ScrollLayout_labelerFormat);
if (labelerFormat == null) {
throw new RuntimeException("Must specify labelerFormat at " + a.getPositionDescription());
}
try {
Class<?> klazz = Class.forName(className);
Constructor<?> ctor = klazz.getConstructor(String.class);
mLabeler = (Labeler)ctor.newInstance(labelerFormat);
} catch (Exception e) {
throw new RuntimeException("Failed to construct labeler at " + a.getPositionDescription(), e);
}
// Determine the width and height of our children, using the labelers preferred
// values as defaults
objWidth = a.getDimensionPixelSize(R.styleable.ScrollLayout_childWidth,
mLabeler.getPreferredViewWidth(context));
objHeight = a.getDimensionPixelSize(R.styleable.ScrollLayout_childHeight,
mLabeler.getPreferredViewHeight(context));
a.recycle();
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
//
// We need to generate enough children to fill all of our desired space, and
// it needs to be an odd number of children because we treat the center view
// specially. So, first compute how many children we will need.
//
final Display display = ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
final int displayWidth = display.getWidth();
int childCount = displayWidth / objWidth;
// Make sure to round up
if (displayWidth % objWidth != 0) {
childCount++;
}
// Now make sure we have an odd number of children
if (childCount % 2 == 0) {
childCount++;
}
// We have an odd number of children, so childCount / 2 will round down to the
// index just before the center in 1-based indexing, meaning that it will be the
// center index in 0-based indexing.
final int centerIndex = (childCount / 2);
// Make sure we weren't inflated with any views for some odd reason
removeAllViews();
// Now add all of the child views, making sure to make the center view as such.
for (int i = 0; i < childCount; i++) {
LayoutParams lp = new LayoutParams(objWidth, objHeight);
TimeView ttv = mLabeler.createView(getContext(), i == centerIndex);
addView((View)ttv, lp);
}
// Now we need to set the times on all of the TimeViews. We start with the center
// view, work our way to the end, then starting from the center again, work our
// way back to the beginning.
mCenterView = (TimeView)getChildAt(centerIndex);
mCenterView.setVals(mLabeler.getElem(currentTime));
Log.v(TAG, "mCenter: " + mCenterView.getTimeText() + " minInterval " + minuteInterval);
// TODO: Do I need to use endTime, or can I just use the point time?
for (int i = centerIndex + 1; i < childCount; i++) {
TimeView lastView = (TimeView)getChildAt(i - 1);
TimeView thisView = (TimeView)getChildAt(i);
thisView.setVals(mLabeler.add(lastView.getEndTime(), 1));
}
for (int i = centerIndex - 1; i >= 0; i--) {
TimeVi
小程序源码 辅助类库 非常漂亮的滚动选择日期控件.rar
版权申诉
66 浏览量
2023-03-29
19:49:22
上传
评论
收藏 55KB RAR 举报
荣华富贵8
- 粉丝: 150
- 资源: 7649
最新资源
- 基于Java的网上订餐系统设计源码 - online ordering system
- 基于Javascript的超级美眉网络资源管理应用模块设计源码
- 基于Typescript和PHP的编程知识储备库设计源码 - study-php
- Screenshot_2024-05-28-11-40-58-177_com.tencent.mm.jpg
- 基于Dart的Flutter小提琴调音器APP设计源码 - violinhelper
- 基于JavaScript和CSS的随寻订购网页设计源码 - web-order
- 基于MATLAB的声纹识别系统设计源码 - VoiceprintRecognition
- 基于Java的微服务插件集合设计源码 - wsy-plugins
- 基于Vue和微信小程序的监理日志系统设计源码 - supervisionLog
- 基于Java和LCN分布式事务框架的设计源码 - tx-lcn
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈