TextView实现文字滚动需要以下几个要点:
1.文字长度长于可显示范围:android:singleLine="true"
2.设置可滚到,或显示样式:android:ellipsize="marquee"
3.TextView只有在获取焦点后才会滚动显示隐藏文字,因此需要在包中新建一个类,继承TextView。重写isFocused方法,这个方法默认行为是,如果TextView获得焦点,方法返回true,失去焦点则返回false。跑马灯效果估计也是用这个方法判断是否获得焦点,所以把它的返回值始终设置为true。
以下转自他人:
Java语言: AlwaysMarqueeTextView 类
public class AlwaysMarqueeTextView extends TextView { public AlwaysMarqueeTextView(Context context) { super(context); } public AlwaysMarqueeTextView(Context context, AttributeSet attrs) { super(context, attrs); } public AlwaysMarqueeTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public boolean isFocused() { return true; }
在布局XML文件中加入这么一个AlwaysMarqueeTextView,这个加入方法也是刚刚学的。
XML语言: layout.xml
<com.examples.AlwaysMarqueeTextView android:id=“@+id/AMTV1″ android:layout_width=“fill_parent” android:layout_height=“wrap_content” android:lines=“1″ android:focusable=“true” android:focusableInTouchMode=“true” android:scrollHorizontally=“true” android:marqueeRepeatLimit=“marquee_forever” android:ellipsize=“marquee” android:background=“@android:color/transparent” />
ellipsize属性
设置当文字过长时,该控件该如何显示。有如下值设置:”start”—–省略号显示在开头;”end”——省略号显示在结尾;”middle”—-省略号显示在中间;”marquee” ——以跑马灯的方式显示(动画横向移动)
marqueeRepeatLimit属性
在ellipsize指定marquee的情况下,设置重复滚动的次数,当设置为marquee_forever时表示无限次。
focusable属性
自己猜测的,应该是能否获得焦点,同样focusableInTouchMode应该是滑动时能否获得焦点。
组合View的问题:
XML语言: 组合View
< LinearLayout xmlns:android =“http://schemas.android.com/apk/res/android” android:orientation =“vertical” android:gravity =“center_vertical” android:background =“@drawable/f_background” android:layout_width =“fill_parent” android:focusable =“true” android:layout_height =“50px” > < TextView android:id =“@+id/info_text” android:focusable =“true” android:layout_width =“fill_parent” android:layout_height =“wrap_content” android:text =“test marquee .. “ android:textColor =“@color/black” android:singleLine =“true” android:ellipsize =“marquee” android:marqueeRepeatLimit =“3″ android:textSize =“18sp” /> < TextView android:id =“@+id/date_text” android:layout_width =“fill_parent” android:layout_height =“wrap_content” android:layout_gravity =“bottom” android:textColor =“@color/gray” android:text =“2010/05/28″ android:textSize =“12sp” /> </ LinearLayout >
上面示例中2个TextView组合为一个View,由于设置了LinearLayout为focusable而TextView就没法取得焦点了,这样 这个TextView的跑马灯效果就显示不出来,就算你也设置TextView的 android:focusable="true" 也是 没用的. 这个时候就要使用addStatesFromChildren 这个属性了,在LinearLayout中设置这个属性,然后设置TextView的focusable= "true" 就可以了.关于 addStatesFromChildren的说明:
Sets whether this ViewGroup's drawable states also include its children's drawable states.
http://hmifly.blog.163.com/blog/static/1285835072011322352406/
------------------------------------------
外面包了几层ViewGroup,都要addStatesFromChildren="true"
开始如下:
可以选择“手动设置”,然后帐户类型选择“IMAP”
这里需要注意的是:
1)系统默认的IMAP服务器是没有前缀的,需要自己添加上“IMAP”的前缀
2)端口设置,网易的端口是993
3)安全类型选择“SSL(接受所有证书)”
单击下一步后,设置“STMP”服务器
1)STMP默认也是没有前缀的,需要自己加上“stmp”的前缀
2)端口是465
3)安全类型是“SSL(接受所有证书)"
单击下一步,后面的就看偶们什么想法了。
第一步:首先在linux下添加驱动
第二步:建立Android测试代码---实现.so文件
第三步:写应用程序
问题一:android NDK jni下的c文件 Unresolved inclusion
问题二:在android 里使用JNI,总是报错:in something not a structure or union
问题三:直接在应用程序中获取驱动的可执行权限#chmod 777
问题四:S5VP210端口设置小结
第一步:首先在linux下添加驱动
1.查看原理图,找出未使用的引脚,这里是:GPJ0_0 GPJ0_1
2.添加char字符设备驱动,找到LINUX源代码下的char设备驱动路径: FriendlyArm /Linux3.0.8/ Drivers/char/目录,在目录下新建里一个文件lzm_fjicc.c 用来写驱动用。
需要注册设备、设备的打开、关闭、取消设备等操作。
源代码如下:
//lzm_fjicc.c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/poll.h>
#include <linux/irq.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <mach/hardware.h>
#include <linux/platform_device.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>
#include <mach/map.h>
#include <mach/gpio.h>
#include <mach/regs-clock.h>
#include <mach/regs-gpio.h>
#define DEVICE_NAME "LZM_FJICC"
static int lzm_gpios[] = {
S5PV210_GPJ0(0),
S5PV210_GPJ0(1),
S5PV210_GPJ0(2),//设置为输入,读取次引脚的状态
};
#define GPIO_NUM ARRAY_SIZE(lzm_gpios)
static int lzm_open(struct inode *inode, struct file *file)
{
int ret;
int i;
for (i = 0; i < GPIO_NUM; i++) {
ret = gpio_request(lzm_gpios[i], "GPIO");
if (ret) {
printk("%s: request GPIO %d failed, ret = %d\n", DEVICE_NAME,
lzm_gpios[i], ret);
return ret;
}
s3c_gpio_cfgpin(lzm_gpios[i], S3C_GPIO_OUTPUT); //设置为输出状态
gpio_set_value(lzm_gpios[i], 1);//默认高电平
}
//set to be input and pullup
s3c_gpio_cfgpin(lzm_gpios[2], S3C_GPIO_INPUT); //设置为输入状态
s3c_gpio_setpull(lzm_gpios[2],S3C_GPIO_PULL_UP);//上拉
// ret = misc_register(&lzm_dev);//register devices to core
printk(DEVICE_NAME"\t open success!\n");
return 0;
}
static int lzm_close(struct inode *inode, struct file *file)
{
int i;
for (i = 0; i < GPIO_NUM; i++) {
gpio_free(lzm_gpios[i]);
}
// misc_deregister(&lzm_dev);
printk(DEVICE_NAME"\t close success! \n");
return 0;
}
static long lzm_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
{
int temp;
switch(cmd) {
case 0://write 0
if (arg > GPIO_NUM) {
return -EINVAL;
}
gpio_set_value(lzm_gpios[arg],0);
//printk(DEVICE_NAME": %d %d\n", arg, cmd);
break;
case 1://write 1
if (arg > GPIO_NUM) {
return -EINVAL;
}
gpio_set_value(lzm_gpios[arg],1);
//printk(DEVICE_NAME": %d %d\n", arg, cmd);
break;
case 3://read GPJ0_2 state //读取端口状态
temp = gpio_get_value(S5PV210_GPJ0(2));
udelay(50);//delay for
printk("read the GPJ0_2 value :%d\n",temp);
return temp;
break;
default:
return -EINVAL;
}
return 0;
}
static struct file_operations dev_fops = {
.owner = THIS_MODULE,
.open = lzm_open,
.unlocked_ioctl = lzm_ioctl,
.release = lzm_close,
};
static struct miscdevice lzm_dev = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &dev_fops,
};
//register device
static int __init dev_init(void)
{
int ret;
ret = misc_register(&lzm_dev);
printk(DEVICE_NAME"\t registered!\n");
return ret;
}
//disregister device
static void __exit dev_exit(void)
{
misc_deregister(&lzm_dev);
printk("\texit!\n");
}
module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");//驱动类型
MODULE_AUTHOR("LZM");//作者信息
MODULE_DESCRIPTION("TEST TEST");//驱动描述
第二步:建立Android测试代码,第一步要实现.so文件:
1.打开eclipseàFileàNewàAndroid Application Project com.example.lzm0922
2.新建jni文件夹,在文件夹内新建两个文件:jni0922.c和Android.mk
Android.mk内容如下:
# Copyright (C) 2009 The Android Open Source Project
#
# 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.
#
LOCAL_PATH := $(call my-dir)
include$(CLEAR_VARS)
LOCAL_MODULE := jni0922
LOCAL_SRC_FILES := jni0922.c
include$(BUILD_SHARED_LIBRARY)
jni0922.c内容如下:
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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.
*
*/
#include<termios.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/ioctl.h>
#include<fcntl.h>
#include<string.h>
#include<jni.h>
#include<errno.h>
//#include <utils/Log.h>
#include<ALog.h>
//#include <system.h>
#define OFF 0x11
#define ON 0x22
#define READ 0x33
#define DEV_NAME "/dev/LZM_FJICC"
int fd;
/* This is a trivial JNI example where we use a native method
* to return a new VM String. See the corresponding Java source
* file located at:
*
* /project/app/TEST/src/com.example.lzm0922/MainActivity.java
* /project/app/TEST/src/com.example.lzm0922/TESTCLASS.java
*/
jstring
Java_com_example_lzm0922_TESTCLASS_stringFromJNI( JNIEnv* env, jobject thiz )
{
return (*env)->NewStringUTF(env, "Hello from JNI !");
}
jint
Java_com_example_lzm0922_TESTCLASS_IOCTL( JNIEnv* env, jobject thiz,jint fd ,jint controlcode,jint ledid )
{
/* LED */
int CTLCODE = controlcode;
int value =-1;
switch(CTLCODE)
{ case ON:
{
ioctl(fd,1,ledid);//setLedState( 0, 1 );//调用驱动程序中的ioctrl接口,把命令传下去,实现硬件操作
break;
}
case OFF:
{
ioctl(fd,0,ledid);//// setLedState( 0, 0 );//调用驱动程序中的ioctrl接口,把命令传下去,实现硬件操作
break;
}
case READ:
{
value=ioctl(fd,3,ledid);// 2 表示读取状态的cmd;0、1表示led控制的命令;
return value;
break;
}
default:break;
}
return 0;
}
jint
Java_com_example_lzm0922_TESTCLASS_OPEN(JNIEnv* env)
{
fd=open(DEV_NAME,O_RDWR);
return fd;
}
int
Java_com_example_lzm0922_TESTCLASS_CLOSE(JNIEnv* env)
{ int ret;
ret = close(fd);
return ret;
}
注意其中的一个头文件Alog.h需要自己写,然后放在jni文件夹下的
#pragma once
#include<android/log.h>
#define LOG_TAG "debug log"
#define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, fmt, ##args)
#define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, fmt, ##args)
#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, fmt, ##args)
3.建立完毕,打开Cygwin工具,并进入到工程目录下的jni目录下:
$ cd d:/Program/Android/workspace/lzm0922/jni
$$NDK/ndk-build
这样就OK了,生成了libjni0922.so文件了,自动生成到了工程目录下的libs/armeabi/ libjni0922.so,发现jni0922是我们刚才在.mk文件里面的命名。
第三步:写应用程序:
1.在应用程序类com.example.lzm0922目录下建立一个类:TESTCLASS.java,输入如下代码,这是用来引用libjni0922.so文件的。
package com.example.lzm0922;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.util.Log;
publicclass TESTCLASS{
public native String stringFromJNI();
publicnativeint OPEN();
public nativeint IOCTL(int fd,int controlcode,int ledID);
public nativeint CLOSE();
static {
try {
System.loadLibrary("jni0922");
} catch (UnsatisfiedLinkError e) {
Log.d("HardwareControler", "HardwareControler ibrary not found!");
}
}
}
2.编写应用程序,调用TESTCLASS类中的函数OPEN()/CLOSE()/IOCTL()就可以实现底层的控制了。
添加两个按钮,用来打开和关闭LED灯,以及读取端口的状态
<Button
android:id="@+id/myButtonOff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="@+id/button1"
android:layout_below="@+id/button1"
android:layout_marginTop="28dp"
android:text="GPJ0_OFF" />
<Button
android:id="@+id/myButtonRd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/myButtonOff"
android:layout_centerVertical="true"
android:text="GPJ0_RD" />
<Button
android:id="@+id/myButtonOn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/myButtonOff"
android:layout_below="@+id/myButtonOff"
android:layout_marginTop="27dp"
android:text="GPJ0_ON" />
2.编写MainActivity,添加响应函数:
package com.example.lzm0922;
import java.io.DataOutputStream;
import java.io.IOException;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
publicclass MainActivity extends Activity {
private Button btn_on,btn_off;
private Button btn_rd;
publicstaticfinalintON = 0x22;
publicstaticfinalintOFF = 0x11;
publicstaticfinalintREAD = 0x33;
intfd;
intvalue = -1;
public String s;
TESTCLASS mTESTCLASS1;
@Override
protectedvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTESTCLASS1 = new TESTCLASS();
s = mTESTCLASS1.stringFromJNI().toString();
//修改驱动的权限LED_LZM_FJICC
changePerm();
fd=mTESTCLASS1.OPEN();
btn_on = (Button)findViewById(R.id.myButtonOn);
btn_off = (Button)findViewById(R.id.myButtonOff);
btn_rd = (Button)findViewById(R.id.myButtonRd);
if(fd == -1)
Toast.makeText(MainActivity.this, "没有打开设备 "+"fd="+fd, Toast.LENGTH_SHORT).show();
else
Toast.makeText(MainActivity.this, "打开设备"+" fd="+fd, Toast.LENGTH_SHORT).show();
Toast.makeText(MainActivity.this,""+s, Toast.LENGTH_SHORT).show();
btn_on.setOnClickListener(new Button.OnClickListener(){
@Override
publicvoid onClick(View arg0) {
// TODO Auto-generated method stub
mTESTCLASS1.IOCTL(fd,ON,0);
}
});
btn_off.setOnClickListener(new Button.OnClickListener(){
@Override
publicvoid onClick(View v) {
// TODO Auto-generated method stub
mTESTCLASS1.IOCTL(fd,OFF,0);
}});
btn_rd.setOnClickListener(new Button.OnClickListener(){
@Override
publicvoid onClick(View v) {
// TODO Auto-generated method stub
value = mTESTCLASS1.IOCTL(fd,READ,1);
Toast.makeText(MainActivity.this, "GPJ0_2="+value, Toast.LENGTH_SHORT).show();
}});
}
@Override
protectedvoid onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Toast.makeText(MainActivity.this, "Close fd="+fd, Toast.LENGTH_SHORT).show();
int temp = mTESTCLASS1.CLOSE();
if(temp == -1)
Toast.makeText(MainActivity.this, "Close Failed fd="+temp, Toast.LENGTH_SHORT).show();
else
Toast.makeText(MainActivity.this, "Close Success fd="+temp, Toast.LENGTH_SHORT).show();
}
void changePerm()
{
Process chperm;
try {
chperm=Runtime.getRuntime().exec("su");
DataOutputStream os =
new DataOutputStream(chperm.getOutputStream());
os.writeBytes("chmod 777 /dev/LZM_FJICC\n");
os.flush();
os.writeBytes("exit\n");
os.flush();
chperm.waitFor();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
问题一:android NDK jni下的c文件 Unresolved inclusion
原因是在eclipse编辑环境中没有找到对应的include中的文件。解决方法是将包含该文件的include目录作为新的linked folder加入工程中。具体方法如下:
1. 右击工程->New->Folder
2. 对话框中点击Advanced
3. 选择Link to alternate location (Linked Folder),选择需要的include目录
4. Finish后刷新工程,问题解决。
include 目录可以在ndk的安装目录中找到
比如:在安装的NDK目录下找到/NDKDir/android-ndk-r7b/platforms/android-8/arch-arm/usr/include
问题二:在android 里使用JNI,总是报错:in something not a structure or union
error: request for member 'GetStringUTFChars' in something not a structure or union
问题解决了,原来是这样的:
如果是c程序,要用 (*env)->
如果是C++要用 env->
在linux下如果.c文件中用 “env->” 编译会找不到此结构,必须用“(*env)->”,或者改成.cpp文件,以 c++的方式来编译
以下是两者的区别:
jni.h中
struct JNINativeInterface_;
struct JNIEnv_;
#ifdef __cplusplus
typedef JNIEnv_ JNIEnv;
#else
typedef const struct JNINativeInterface_ *JNIEnv;
#endif
/*
* We use inlined functions for C++ so that programmers can write:
* env->FindClass("java/lang/String")
* in C++ rather than:
* (*env)->FindClass(env, "java/lang/String")
* in C.
*/
即C++中使用
env->FindClass("java/lang/String")
C中使用
(*env)->FindClass(env, "java/lang/String")
问题三:直接在应用程序中获取驱动的可执行权限#chmod 777
//用来修改驱动的权限问题否则需要在终端输入 #chmod 777 /dev/LZM_FJICC
void changePerm()
{
Process chperm;
try {
chperm=Runtime.getRuntime().exec("su");
DataOutputStream os =
new DataOutputStream(chperm.getOutputStream());
os.writeBytes("chmod 777 /dev/LZM_FJICC\n");
os.flush();
os.writeBytes("exit\n");
os.flush();
chperm.waitFor();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
问题四:S5VP210端口设置小结
// 定义用到的引脚 S5PV210_GPJ0(7)
// 设置引脚的输出
s3c_gpio_cfgpin(S5PV210_GPJ0(7),S3C_GPIO_SFN(1));//设置为输出
gpio_direction_output(S5PV210_GPJ0(7),0);
//释放总线
#define OW_Pin S5PV210_GPJ0(7)
s3c_gpio_cfgpin(OW_Pin,S3C_GPIO_SFN(0));//设置为输入
s3c_gpio_setpull(OW_Pin,S3C_GPIO_PULL_UP);
gpio_get_value(OW_Pin)//获取引脚的输入电平状态