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属性,改变样式