mainActivity如下:
package c.x; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MainActivity extends Activity { private Button mStartbButton; private Button mPauseButton; private Button mRestartbButton; private MarqueeText mMarqueeText; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); init(); } private void init(){ mMarqueeText=(MarqueeText) findViewById(R.id.marqueeText); mStartbButton=(Button) findViewById(R.id.start_Button); mStartbButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { mMarqueeText.startScroll(); } }); mPauseButton=(Button) findViewById(R.id.pause_Button); mPauseButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { mMarqueeText.pauseScroll(); } }); mRestartbButton=(Button) findViewById(R.id.restart_Button); mRestartbButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { mMarqueeText.restartScroll(); } }); } }
MarqueeText如下:
package c.x; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.util.AttributeSet; import android.widget.TextView; /** * 需求描述: * TextView跑马灯的实现 * * 实现原理: * 通过不断的scrollTo()显示View中不同坐标处的内容 * *遇到的问题 *1 注意scrollTo(int x, int y) * 移动View中内容,比如此处TextView中的文字. * x the x position to scroll to * y the y position to scroll to * *2 scrollTo(int x, int y)的坐标问题 * 参考资料: * http://www.open-open.com/lib/view/open1328834050046.html * 个人理解: * 该坐标为View中的内容的坐标.该坐标的起始点虽然在内容的左上角 * 但是Y轴的正向是竖直向上的,X轴水平向右. * 该理解待于进一步验证. * */ public class MarqueeText extends TextView implements Runnable { private int contentWidth=0; private int scrollToX=0; private boolean isStop=false; private boolean isRun=true; private boolean isMeasureContentWidth=false; public MarqueeText(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (!isMeasureContentWidth) { //获取文字长度 Paint paint=this.getPaint(); String content=this.getText().toString(); contentWidth=(int) paint.measureText(content); isMeasureContentWidth=true; } } public void run() { if (isRun) { if (scrollToX>=contentWidth) { //重新开始 scrollToX=-150; } scrollTo(scrollToX, 0); scrollToX=scrollToX+5; postDelayed(this, 150); } } // 点击开始,执行线程 public void startScroll() { post(this); } // 点击暂停 public void pauseScroll() { isRun=false; } // 点击重新开始 public void restartScroll() { isRun=true; scrollToX=0; startScroll(); } }
main.xml如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <LinearLayout android:id="@+id/linerLayout" android:layout_width="match_parent" android:layout_height="80dip" android:layout_alignParentTop="true" android:orientation="horizontal" > <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent" > <Button android:id="@+id/start_Button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:text="开始" /> <Button android:id="@+id/pause_Button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:text="暂停" /> <Button android:id="@+id/restart_Button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:text="重新开始" /> </RelativeLayout> </LinearLayout> <c.x.MarqueeText android:id="@+id/marqueeText" android:layout_width="200dip" android:layout_height="100dip" android:layout_below="@id/linerLayout" android:text="波什29分4篮板2抢断4盖帽,雷-阿伦15分" android:textColor="@android:color/black" android:background="@android:color/white" android:ellipsize="marquee" android:singleLine="true" android:gravity="center_vertical" /> </RelativeLayout>
前几章参考:
1-引言
2-Objective-C 编程
3-类、对象和方法
4-数据类型和表达式
5-循环结构
6-选择结构
要注意的一件事情(这个和C语言差不多,就是头文件引用规则):
导入的文件要用一对引号引起来,而不是<Foundation/Foundation.h>中的“<”和">"字符。双引号适用于本地文件(你自己创建的文件),而不是系统文件,这样就通知编译器在哪里能够找到指定的文件。
接口和实现的要求:
接口文件包含类的公开信息,即能够与这个类的使用者共享一些信息。另一方面,实现部分包含的是私有信息,即实例变量和代码。
合成存取方法:
从Objective-C2.0开始,可自动生成设值方法和取值方法(统称为存取方法)。具体步骤如下:
1)在接口部分中使用@property指令标识属性。
@interface Fraction : NSObject
@property int numerator, denominator;
@end
2)在实现部分使用@synthesize指令即可。
@inplementation Fraction
@synthesize numerator, denominator;
@end
如果使用了@property指令,就不需要在实现部分声明相应的实例变量。
通常,如果有称为x的属性,那么在实现部分包括以下行会导致编译器自动实现一个取值方法x和一个设置方法setX:
@synthesize x;
因为生成的存取方法是高效的,并且在使用多个核心的多台机器上,使用多线程时也可正常运行。(这里的说法呢,就是说线程安全的)
访问属性:
可以使用点运算符.,或发送消息[]
[myFraction numerator];
myFraction.numerator;
一般格式:
instance.property = value;
等价于
[instance setProperty: value]
需要指出的是,也可以对自定义的方法使用点运算符,不仅仅是使用在synthesize上(即属性)。
注意:
点运算符和发消息都是可以的,但是,点运算符通常使用在属性上,用于设置或取得实例变量的值。方法在Apple的文档中被标记为任务(Task),任务通常不是由dian运算符执行的,而是使用传统的方括号形式的消息表达式作为首选的语法。
另外,使用合成(synthesize)的存取方法,属性名称的前面不要以new、alloc、copy和init这些此开头。这与编译器的一些假定有关,因为编译器会合成相应的方法。
关于方法:
在编写新方法时,省略参数名不是一种好的编程风格,因为它是程序很难读懂并且很不直观,特别是当使用的方法参数特别重要时,更是如此。
[aFraction set:1 :3]这是不好的
[aFraction set:1 over:3]这是好的
- (void)add:(Fraction *) f;
这条语句说明add:方法的参数是Fraction类对象的一个引用。星号是必须的,所以声明(Fraction) f是不正确的。
局部变量:
局部变量是基本的C数据类型,并没有默认的初始值,所以在使用前要先赋值。局部对象变量默认初始化为nil。和实例变量不同(它们在多次方法调用时保持自己的值),这些局部变量没有记忆力。也就是说,当方法返回时,这些变量的值都消失了。每次调用方法时,该方法中的局部变量都使用变量声明重新初始化一次。
方法的参数:
方法的参数名也是局部变量。执行方法时,通过方法传递的任何参数都被复制到局部变量中。因为方法使用参数的副本,所以不能改变通过方法传递的原值。这一点很重要。
另外,如果参数是对象,可以更改其中的实例变量值。当你传递一个对象作为参数时,实际上是传递了一个数据存储位置的引用。正因为如此,你才能够修改这些数据。
static关键字:
在变量声明前加上关键字static,可以使局部变量保留多次调用一个方法所得的值。和其它基本数据类型的局部变量不同。静态变量的初始值为0。此外,它们只在程序开始执行时初始化一次,并且在多次调用方法时保存这些数值。
记住:只能在定义静态变量和局部变量的方法中访问这些变量。
总的说来,这一章里面的很过概念还是比较重要的,在别的语言里也有描述这些。
List<String> list = new ArrayAdapter<String>;
list.add(“test1”);
list.add(“test2”);
ArrayAdapter adpter = new ArrayAdapter(this,R.layout.item,R.id.textId,list);
Spinner.setAdapter(adapter);
Spinner.serPrompt(“标题”); //设置spinner展开后框体的title
第一个参数指上下文对象
第二个参数指定下拉框的样式
第三个参数指定TextView的id,R.id.textid 在R.layout.item中定义
第四个参数提供数据源
package com.example.sp; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.View; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.Spinner; public class MainActivity extends Activity { private Spinner spinner; private Button bt; private List<String> list ; @SuppressWarnings("unused") @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); spinner = (Spinner)findViewById(R.id.spinner); bt = (Button)findViewById(R.id.bt); list = new ArrayList<String>(); list.add("text"); list.add("text"); ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.item, R.id.text,list); spinner.setAdapter(adapter); spinner.setPrompt("ceshi"); bt.setOnClickListener(new Button.OnClickListener() { public void onClick(View v) { // TODO Auto-generated method stub list.add("要添加的数据"); } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } }Item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/text" android:layout_width="fill_parent" android:layout_height="wrap_content"> </TextView> </LinearLayout>
Activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:orientation="vertical" android:layout_height="fill_parent" > <Spinner android:id="@+id/spinner" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/bt" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="add" > </Button> </LinearLayout>
为了使样式更好看,可以让设置TextView属性,改变样式