package com.Runner_Widget;
import com.Runner_Widget.R;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.view.animation.Animation.AnimationListener;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
public class Runner extends LinearLayout{
public class ScrollContainer extends ScrollView
{
public ScrollContainer(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
//去掉滚动条
this.setVerticalScrollBarEnabled(false);
}
//去掉触摸效果
public boolean onTouchEvent (MotionEvent ev)
{
return false;
}
};
private final int MIN_ITEM_AMOUNT = 3;
//private final int FIXED_ITEM_AMOUNT = 6;
//private final int MARGIN_ITEM_AMOUNT = 2;
private final String TextViewTag = "Text";
private final String ORIENTATION_HORIZONTAL = "horizontal";
private final String ORIENTATION_VERTICAL = "vertical";
private LinearLayout HContent = null;
private ScrollContainer ScrollContainer = null;
private LinearLayout mContent = null;
private LinearLayout txtContent1;
private LinearLayout txtContent2;
private LinearLayout txtContent3;
private LinearLayout txtContent4;
private LinearLayout txtContent5;
private LinearLayout txtContent6;
private LinearLayout txtContent7;
private TextView txt1 = null;
private TextView txt2 = null;
private TextView txt3 = null;
private TextView txt4 = null;
private TextView txt5 = null;
private TextView txt6 = null;
private TextView txt7 = null;
private Animation gravityAnim = null;
private Context parentContext = null;
private AttributeSet parentAttrs = null;
private LayoutParams fixedParams = null;
private int itemHeight = 0;
//private float transStep = 0.0f;
private int contentMinHeight = 0;
//private int itemAmounts = 3;
private int textSize = 30;
private int currentPos = 0;
private int lastPos = 0;
//private int posTo = 0;
//private int posBy = 0;
//private float currentY = 0.0f;
//private float lastY = 0.0f;
private float gravityOffset = 0.0f;
private boolean enableGravity = false;
private boolean enableAnimation = true;
private int duration_gravity = 0;
//private boolean animating = false;
private String[] adapter = {"000", "001", "002", "003", "004", "005"};
private Handler mHandler = new Handler();
private Runnable PostScroll = new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
//ScrollContainer.smoothScrollBy(0, posTo);
if(true == enableAnimation)
{
ScrollContainer.smoothScrollTo(0, currentPos * itemHeight);
if(true == enableGravity)
{
HContent.startAnimation(gravityAnim);
}
}
else
{
ScrollContainer.scrollTo(0, currentPos * itemHeight);
}
Log.v("pos", Integer.toString(currentPos));
Log.v("Scroll", Integer.toString(currentPos * itemHeight));
}
};
public Runner(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
parentAttrs = attrs;
parentContext = context;
fixedParams = generateLayoutParams(attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Runner);
//获取参数
gravityOffset = a.getFloat(R.styleable.Runner_gravityoffset, 0.0f);
enableGravity = a.getBoolean(R.styleable.Runner_enable_gravity, true);
enableAnimation = a.getBoolean(R.styleable.Runner_enable_animation, true);
duration_gravity = a.getInt(R.styleable.Runner_duration_gravity, 300);
textSize = a.getInt(R.styleable.Runner_text_size, 0);
a.recycle();
//根据背景固定本类对象的长宽
Drawable d = a.getDrawable(R.styleable.Runner_background);
this.setEnabled(true);
LayoutParams params = generateLayoutParams(attrs);
params.width = d.getIntrinsicWidth();
params.height = d.getIntrinsicHeight();
this.setLayoutParams(params);
//计算单个项目(容纳textView的容器)的高度
contentMinHeight = d.getIntrinsicHeight();
itemHeight = contentMinHeight / MIN_ITEM_AMOUNT;
if(0 != contentMinHeight % MIN_ITEM_AMOUNT)
{
itemHeight++;
}
//transStep = itemHeight;
//创建一个横向相对布局,使其中内容横向居中
HContent = CreateCenterHContent(context, attrs);
HContent.setEnabled(true);
if(null != HContent)
{
this.addView(HContent);
}
//创建一个ScrollView,承载整个布局
ScrollContainer = CreateScrollViewContainer(context, attrs);
if((null != HContent) && (null != ScrollContainer))
{
HContent.addView(ScrollContainer);
}
//创建一个纵向或者横向相对布局,大小与自身相同,放入其中
CreateContentLayout(context, attrs);
if((null != mContent) && (null != ScrollContainer))
{
ScrollContainer.addView(mContent);
}
//初始化文本容器并添加到父容器中
CreateTextContentLayout(context, attrs);
//创建文本控件,并放入mContent中
AddText2TextContentLayout(context, attrs);
}
public LinearLayout CreateCenterHContent(Context context, AttributeSet attrs)
{
LinearLayout layout = new LinearLayout(context, attrs);
LayoutParams params = generateLayoutParams(attrs);
params.width = LayoutParams.MATCH_PARENT;
//params.height = LayoutParams.WRAP_CONTENT;
params.height = contentMinHeight;
params.gravity = Gravity.CENTER_HORIZONTAL;
if(null != layout)
{
layout.setLayoutParams(params);
layout.setMinimumHeight(contentMinHeight);
layout.setGravity(Gravity.CENTER_HORIZONTAL);
}
return layout;
}
private ScrollContainer CreateScrollViewContainer(Context context, AttributeSet attrs)
{
ScrollContainer view = new ScrollContainer(context, attrs);
view.setSmoothScrollingEnabled(true);
view.setVerticalFadingEdgeEnabled(true);
//view.setScrollbarFadingEnabled(true);
//view.setScrollBarStyle(SCROLLBARS_INSIDE_OVERLAY);
return view;
}
public void CreateContentLayout(Context context, AttributeSet attrs)
{
LayoutParams params = generateLayoutParams(attrs);
params.width = LayoutParams.WRAP_CONTENT;
params.height = LayoutParams.WRAP_CONTENT;
if(null == mContent)
{
mContent = new LinearLayout(context, attrs);
mContent.setLayoutParams(params);
mContent.setMinimumHeight(contentMinHeight);
mContent.setOrientation(LinearLayout.VERTICAL);
mContent.setEnabled(true);
}
}
public void CreateTextContentLayout(Context context, AttributeSet attrs)
{
LayoutParams params = generateLayoutParams(attrs);
params.width = LayoutParams.WRAP_CONTENT;
params.height = itemHeight;
LinearLayout txtContent0 = new LinearLayout(context, attrs);
txtContent0.setLayoutParams(params);
txtContent0.setOrientation(LinearLayout.VERTICAL);
txtContent0.setGravity(Gravity.CENTER_VERTICAL);
if((null != mContent) && (null != txtContent0))
{
mContent.addView(txtContent0);
}
txtContent1 = new LinearLayout(context, attrs);
txtContent1.setLayoutParams(params);
txtContent1.setOrientation(LinearLayout.VERTICAL);
txtContent1.setGravity(Gravity.CENTER_VERTICAL);
if((null != mContent) && (null != txtContent1))
{
mContent.addView(txtContent1);
}
txtContent2 = new LinearLayout(context, attrs);
txtContent2.setLayoutParams(params);
txtContent2.setOrientation(LinearLayout.VERTICAL);
txtContent2.setGravity(Gravity.CENTER_VERTICAL);
if((null != mContent) && (null != txtContent2))
{
mContent.addView(txtContent2);
}
txtContent3 = new LinearLayout(context, attrs);
txtContent3.setLayoutParams(params);
txtContent3.setOrientation(LinearLayout.VERTICAL);
txtContent3.setGravity(Gravity.CENTER_VERTICAL);
if((null != mContent) && (null != txtContent3))
{
mContent.addView(txtContent3);
}
txtContent4 = new LinearLayout(context, attrs);
txtContent4.setLayoutParams(params);
txtContent4.setOrientation(LinearLayout.VERTICAL);
txtContent4.setGravity(Gravity.CENTER_VERTICAL);
if((null != mContent) && (null != txtContent4))
{
mContent.addView(txtContent4);
}
txtContent5 = new LinearLayout(context, attrs);
txtContent5.setLayoutParams(params);
txtContent5.setOrientation(LinearLayout.VERTICAL);
txtContent5.setGravity(Gravity.CENTER_VERTICAL);
if((null != mContent) && (null != txtContent5))
{
mContent.addView(txtContent5);
}
txtContent6 = new LinearLayout(context, attrs);
txtContent6.setLayoutParams(params);
txtContent6.setOrientation(LinearLayout.VERTICAL);
txtContent6.setGravity(Gravity.CENTER_VERTICAL);
if((null != mContent) && (null != txtContent6))
{
mContent.addView(txtContent6);
}
txtContent7 = new LinearLayout(context, attrs);
txtContent7.setLayoutParams(params);
txtContent7.setOrientation(LinearLayout.VERTICAL);
txtContent7.setGravity(Gravity.CENTER_VERTICAL);
if((null != mContent) && (null != txtContent7))
{
mContent.addView(txtContent7);
}
}
public void AddText2TextContentLayout(Context context, AttributeSet attrs)
{
txt1 = CreateTextView(context, attrs, "000", textSize);
txtContent1.addView(txt1);
txt2 = CreateTextView(context, attrs, "001", textSize);
txtContent2.addView(txt2);
txt3 = CreateTextView(context, attrs, "002", textSize);
txtContent3.addView(txt3);
txt4 = CreateTextView(context, attrs, "003", textSize);
txtContent4.addView(txt4);
txt5 = CreateTextView(context, attrs, "004", textSize);
txtContent5.addView(txt5);
txt6 = CreateTextView(context, attrs, "005", textSize);
txtContent6.addView(txt6);
txt7 = CreateTextView(context, attrs, "", textSize);
txtContent7.addView(txt7);
}
public TextView CreateTextView(Context context, AttributeSet attrs, String str, int textSize)
{
TextView txt = new TextView(context, attrs);
txt.setText(str);
txt.setTextColor(Color.BLACK);
txt.setTextSize(textSize);
return txt;
}
public int GetPos()
{
return currentPos;
}
public int GetItemAmount()
{
return mContent.getChildCount();
}
public int GetContentHeight()
{
return contentMinHeight;
}
public void SetPos(int pos)
{
ScrollContent(pos);
}
public void ScrollContent(int pos)
{
if((pos >= 0) && (pos < adapter.length))
{
lastPos = currentPos;
currentPos = pos;
//显示反弹效果
if(true == enableAnimation)
{
float offset = 0;
if(currentPos < lastPos)
{
offset = gravityOffset;
}
else if(currentPos > lastPos)
{
offset = -gravityOffset;
}
gravityAnim = new TranslateAnimation(0, 0, 0, offset);
gravityAnim.setDuration(duration_gravity);
gravityAnim.setFillEnabled(true);
gravityAnim.setFillAfter(true);
gravityAnim.setAnimationListener(new AnimationListener(){
@Override
public void onAnimationEnd(Animation animation) {
// TODO Auto-generated method stub
float offset = 0;
if(currentPos < lastPos)
{
offset = gravityOffset;
}
else if(currentPos > lastPos)
{
offset = -gravityOffset;
}
Animation bounceAnim = new TranslateAnimation(0, 0, offset, -offset);//不知为何这样才对,如果从offset到0,则不能复位
bounceAnim.setDuration(duration_gravity);
bounceAnim.setFillEnabled(true);
bounceAnim.setFillAfter(true);
startAnimation(bounceAnim);
}
@Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
});
}
if(null != mHandler)
{
mHandler.post(PostScroll);
}
}
}
public void SetEnableGravity(boolean b)
{
enableGravity = b;
}
/* ---------------------------------------------------------------------------------------
* SetArrayAdapter(String[] array)
* 设置要显示的参数
* --------------------------------------------------------------------------------------*/
public void SetArrayAdapter(String[] array)
{
int currentItemCount;
//更新数据
adapter = array;
currentItemCount = GetItemsCount() - 2;//首尾两个控件起填充作用
if(adapter.length < currentItemCount)//截短控件组再更新文本
{
for(int i = 0; i < currentItemCount; i++)
{
if(i < adapter.length)//更新文本
{
FindTextViewByIndex(i + 1).setText(adapter[i]);
}
else if(i == adapter.length)//清空文本
{
FindTextViewByIndex(i + 1).setText("");
}
else//删除控件
{
RemoveAllLastChildViews(i + 1);
//RemoveChildViewGroupAt(i + 1);//
}
}
}
else if(adapter.length == currentItemCount)//只需更新文本
{
for(int i = 0; i < currentItemCount; i++)
{
FindTextViewByIndex(i + 1).setText(adapter[i]);
}
}
else//增加控件组再更新文本
{
for(int i = 0; i <= adapter.length; i++)
{
if(i <= currentItemCount)//更换文本
{
FindTextViewByIndex(i + 1).setText(adapter[i]);
}
else if(i < adapter.length)//增加控件并填充文本
{
AddItem2ScrollField(adapter[i]);
}
else if(i == adapter.length)
{
AddItem2ScrollField("");
}
}
}
}
/* ---------------------------------------------------------------------------------------
* SetArrayAdapter(String[] array)
* 设置要显示的参数对
* --------------------------------------------------------------------------------------*/
public void SetPairArrayAdapter(String[] array)
{
}
private int GetItemsCount()
{
return mContent.getChildCount();
}
private void RemoveAllLastChildViews(int from)
{
int to = mContent.getChildCount();
for(int i = from; i < to; i++)
{
RemoveChildViewGroupAt(from);
}
}
private void RemoveChildViewGroupAt(int index)
{
mContent.removeViewAt(index);
Log.v("Removal", Integer.toString(mContent.getChildCount()));
}
private TextView FindTextViewByIndex(int ind)
{
TextView t = null;
switch(ind)
{
case 1:t = txt1;break;
case 2:t = txt2;break;
case 3:t = txt3;break;
case 4:t = txt4;break;
case 5:t = txt5;break;
case 6:t = txt6;break;
case 7: t = txt7;break;
default:
t = (TextView)mContent.getChildAt(ind).findViewWithTag(TextViewTag);
break;
}
return t;
}
private void AddItem2ScrollField(String text)
{
LinearLayout content = CreateTextContent();
TextView txt = CreateTextView(text);
if(null != content)
{
content.addView(txt);
if(null != mContent)
{
mContent.addView(content);
}
}
}
private LinearLayout CreateTextContent()
{
LinearLayout layout = new LinearLayout(parentContext, parentAttrs);
fixedParams.width = LayoutParams.WRAP_CONTENT;
fixedParams.height = itemHeight;
layout.setLayoutParams(fixedParams);
layout.setOrientation(LinearLayout.VERTICAL);
layout.setGravity(Gravity.CENTER_VERTICAL);
return layout;
}
private TextView CreateTextView(String txt)
{
TextView text = new TextView(parentContext, parentAttrs);
text.setText(txt);
text.setTag(TextViewTag);
text.setTextColor(Color.BLACK);
text.setTextSize(textSize);
return text;
}
}
package com.Runner_Widget;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.LayoutAnimationController;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
public class Runner_Widget extends Activity {
/** Called when the activity is first created. */
Button nextAnim;
Button increase;
Button decrease;
Runner mRunner;
FrameLayout content;
public int pos = 0;
String[] chanLst;
EditText mText;
boolean running = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//初始化chanLst
InitChanLst();
content = (FrameLayout)findViewById(R.id.frameLayout1);
mText = (EditText)findViewById(R.id.editText1);
mRunner = (Runner)findViewById(R.id.runner1);
nextAnim = (Button)findViewById(R.id.button1);
increase = (Button)findViewById(R.id.button3);
decrease = (Button)findViewById(R.id.button2);
nextAnim.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
char[] aa;
aa = mText.getText().toString().toCharArray();
for(char a:aa)
{
pos = pos * 10 + a - 0x30;
}
mRunner.ScrollContent(pos);
pos = 0;
}
});
increase.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
String[] str = new String[]{"000 10.000000", "001 10.100000", "002 10.200000",
"003 10.300000", "004 10.400000", "005 10.500000",
"006 10.600000", "007 10.700000", "008 10.800000"};
mRunner.SetArrayAdapter(str);
}
});
decrease.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
String[] str = new String[]{"您好!", "请慢用!"};
mRunner.SetArrayAdapter(str);
}
});
// int layoutHeight = mRunner.GetContentHeight();
// LayoutParams params = content.getLayoutParams();
// params.height = layoutHeight;
// content.setLayoutParams(params);
new Thread(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
int pos;
while(running)
{
pos = mRunner.GetPos();
if(pos == mRunner.GetItemAmount() - 3)
{
pos = 0;
}
else
{
pos++;
}
mRunner.SetPos(pos);
try {
Log.v("timer", "pos"+Integer.toString(pos));
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
}
@Override
public void onDestroy() {
super.onDestroy();
running = false;
}
@Override
public void onStart() {
super.onStart();
running = true;
}
public void InitChanLst()
{
chanLst = new String[]{"000", "001", "002", "003"};
}
}