Android 开发之旅

本文介绍了两种实现Android跑马灯效果的方法:一种是利用TextView自带属性,另一种是通过自定义View类。同时探讨了自定义View类时父类构造函数的区别,并提供了具体的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本次暑假正式接触Android开发,现在已经开学快一个月了,抽空闲时间,将自己在暑假中的学习,做一些总结。也为以后分析Android源码的学习,做些准备工作。

1.文字跑马灯效果的实现。

方式一:通过TextView控件自带的属性的设置完成文字跑马灯效果

   <TextView android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="#333333" 
        android:ellipsize="marquee" //跑马灯效果
        android:focusable="true" //控件是否能够获取焦点
        android:marqueeRepeatLimit="marquee_forever" //表示无数次的重复显示
        android:focusableInTouchMode="true" //是否在触摸模式下获得焦点
        android:scrollHorizontally="true"//相当于android:singleline="true"设置单行显示效果
        android:text="当要显示的文字超过了屏幕的宽度时,就会以跑马灯的效果显示文字"
        >
    </TextView>


可以参考的资料有:http://www.cnblogs.com/over140/archive/2010/08/20/1804770.html(农民伯伯)      http://xiangqianppp-163-com.iteye.com/blog/1473555(弄月)

方式二:通过自己实现一个View类来实现跑马灯效果

由于自己的水平有限,无法独立的完成自定义控件的代码,但印象中,有些需要一些自己想要的效果时,总是需要自定义控件,继承自View类,来实现自己想要的效果,比如,百度地图给提供的一个地图视图就是自定义组件来显示,使用自定义的组件和使用Android本身自带的控件的用法是基本类似的,在布局文件中,给出<项目包名.组件名>就可以了。还有一类常见的是继承BaseAdapter来实现自己想要的适配器效果。循着这条思路,就有了下面的学习资料

Android开发——构建自定义组件     http://blog.chinaunix.net/uid-22957718-id-61532.html

Android自定义控件总结    http://blog.youkuaiyun.com/zmlsc888/article/details/7947621

通过上述两篇文章,对于自定义控件时,大致的思路有一定的指导。


先说一下自定义View控件时,父类的三个构造函数的区别(本次的代码中有用到)

public class AutoScrollTextView extends TextView  implements OnClickListener {
	 public final static String TAG = AutoScrollTextView.class.getSimpleName();
	    
	    private float textLength = 0f;//文本长度
	    private float viewWidth = 0f;
	    private float step = 0f;//文字的横坐标
	    private float y = 0f;//文字的纵坐标
	    private float temp_view_plus_text_length = 0.0f;//用于计算的临时变量
	    private float temp_view_plus_two_text_length = 0.0f;//用于计算的临时变量
	    public boolean isStarting = false;//是否开始滚动
	    private Paint paint = null;//绘图样式
	    private String text = "";//文本内容

	    
	    public AutoScrollTextView(Context context) {
	        super(context);
	        initView();
	    }

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

	    public AutoScrollTextView(Context context, AttributeSet attrs, int defStyle) {
	        super(context, attrs, defStyle);
	        initView();
	    }
	    
	    /**
	     * 初始化控件
	     */
	    private void initView()
	    {
	        setOnClickListener(this);
	    }
	    
	    /**
	     * 文本初始化,每次更改文本内容或者文本效果等之后都需要重新初始化一下
	     */
	    public void init(WindowManager windowManager)
	    {
	        paint = getPaint();
	        text = getText().toString();
	        textLength = paint.measureText(text);
	        viewWidth = getWidth();
	        if(viewWidth == 0)
	        {
	            if(windowManager != null)
	            {
	                Display display = windowManager.getDefaultDisplay();
	                viewWidth = display.getWidth();
	            }
	        }
	        step = textLength;
	        temp_view_plus_text_length = viewWidth + textLength;
	        temp_view_plus_two_text_length = viewWidth + textLength * 2;
	        y = getTextSize() + getPaddingTop();
	    }
	    
	    @Override
	    public Parcelable onSaveInstanceState()
	    {
	        Parcelable superState = super.onSaveInstanceState();
	        SavedState ss = new SavedState(superState);
	        
	        ss.step = step;
	        ss.isStarting = isStarting;
	        
	        return ss;
	        
	    }
	    
	    @Override
	    public void onRestoreInstanceState(Parcelable state)
	    {
	        if (!(state instanceof SavedState)) {
	            super.onRestoreInstanceState(state);
	            return;
	        }
	        SavedState ss = (SavedState)state;
	        super.onRestoreInstanceState(ss.getSuperState());
	        
	        step = ss.step;
	        isStarting = ss.isStarting;

	    }
	    
	    public static class SavedState extends BaseSavedState {
	        public boolean isStarting = false;
	        public float step = 0.0f;
	        SavedState(Parcelable superState) {
	            super(superState);
	        }

	        @Override
	        public void writeToParcel(Parcel out, int flags) {
	            super.writeToParcel(out, flags);
	            out.writeBooleanArray(new boolean[]{isStarting});
	            out.writeFloat(step);
	        }


	        public static final Parcelable.Creator<SavedState> CREATOR
	                = new Parcelable.Creator<SavedState>() {
	            
	            public SavedState[] newArray(int size) {
	                return new SavedState[size];
	            }

	            @Override
	            public SavedState createFromParcel(Parcel in) {
	                return new SavedState(in);
	            }
	        };

	        private SavedState(Parcel in) {
	            super(in);
	            boolean[] b = null;
	            in.readBooleanArray(b);
	            if(b != null && b.length > 0)
	                isStarting = b[0];
	            step = in.readFloat();
	        }
	    }

	    /**
	     * 开始滚动
	     */
	    public void startScroll()
	    {
	        isStarting = true;
	        invalidate();
	    }
	    
	    /**
	     * 停止滚动
	     */
	    public void stopScroll()
	    {
	        isStarting = false;
	        invalidate();
	    }
	    

	    @Override
	    public void onDraw(Canvas canvas) {
	        canvas.drawText(text, temp_view_plus_text_length - step, y, paint);
	        if(!isStarting)
	        {
	            return;
	        }
	        step += 0.5;
	        if(step > temp_view_plus_two_text_length)
	            step = textLength;
	        invalidate();

	    }

	    @Override
	    public void onClick(View v) {
	        if(isStarting)
	            stopScroll();
	        else
	            startScroll();
	        
	    }


}

public View (Context context)是在java代码创建视图的时候被调用,如果是从xml填充的视图,就不会调用这个
public View (Context context, AttributeSet attrs)这个是在xml创建但是没有指定style的时候被调用
public View (Context context, AttributeSet attrs, int defStyle)在xml创建并且指定了style的时候会被调用。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值