2、在原生的android源码上添加这一功能。
思路:先把界面做出来,再将是否选择的值存到系统的(adb shell进入)data/data/com.android.providers.settings/databases/settings.db数据库中的system表中,
然后在Launch2的源码中取得数据库中是否选择循环桌面来执行相关代码。
先做UI:
在settings源码中的accessibility_settings.xml文件中添加一个checkbox:
java代码
android:key="launch_repeat"
android:title="@string/launch_repeat_title"
android:persistent="false"/>
在settings源码的res中添加相关的代码:
在values/string.xml中添加(英文显示):
Launch Repeat
在values-zh-rCN/string.xml中添加(中文显示):
"循环桌面"
在settings源码的AccessibilitySettings.java中的OnCreate中添加:
java代码
/*****************************************/
mLaunchRepeat=(CheckBoxPreference) findPreference(
LAUNCH_REPEAT)
int LaunchRepeat=Settings.System.getInt(this.getContentResolver(),
"launch_repeat",0)//取出是否被选择
if(LaunchRepeat==1)//如果被选择,那么下次打开setting时就勾选
mLaunchRepeat.setChecked(true)
else
mLaunchRepeat.setChecked(false)//如果没被选择,那么下次打开setting时就不勾选
/*****************************************/
当然还要定义几个量:
private final String LAUNCH_REPEAT =
"launch_repeat"
private CheckBoxPreference mLaunchRepeat
在onPreferenceTreeClick函数中添加:
java代码
//add by xxnan
if(LAUNCH_REPEAT.equals(key))
{
Settings.System.putInt(getContentResolver(),
"launch_repeat",
((CheckBoxPreference) preference).isChecked()?
1:0)//将是否选择存到系统的system表中
}
//add by xxnan
如果做好了之后当点击选择“桌面循环时”可以到(adb shell进入)data/data/com.android.providers.settings/databases下的settings.db数据库(sqlite3 settings.db)的system
表中看到33|launch_repeat|1(select * from system)。
到这里就完成了将数据存到系统system表中以及UI,接下来就是在Launch2源码中去取这个值(是否循环)。
到Launcher2源码中去找到Workspace.java文件,在里面有相应的修改:
在onTouchEvent中,之前有修改循环,如下:
java代码
case MotionEvent.ACTION_UP:
if (mTouchState == TOUCH_STATE_SCROLLING) {
final VelocityTracker velocityTracker = mVelocityTracker
velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity)
final int velocityX = (int)
velocityTracker.getXVelocity(mActivePointerId)
final int screenWidth = getWidth()
final int whichScreen = (mScrollX + (screenWidth / 2)) / screenWidth
final float scrolledPos = (float) mScrollX / screenWidth
Log.i("velocityX","velocityX="+velocityX+"whichScreen="+whichScreen)
/***********************************************/
//modifided by xxnan
if (velocityX >SNAP_VELOCITY) {
// Fling hard enough to move left.
// Don't fling across more than one screen at a time.
Log.i("numscreen","numscreen="+mCurrentScreen)
/* final int bound = scrolledPos <whichScreen ?
( (mCurrentScreen+ getChildCount()) - 1 )% getChildCount():
mCurrentScreen*/
final int bound =( (mCurrentScreen+ getChildCount()) - 1 )% getChildCount()
Log.i("numscreen","bound="+bound)
snapToScreen( bound, velocityX, true)
} else if (velocityX <-SNAP_VELOCITY ) {
// Fling hard enough to move right
// Don't fling across more than one screen at a time.
/*final int bound = scrolledPos >whichScreen ?
( mCurrentScreen + 1 )% getChildCount(): mCurrentScreen*/
final int bound = ( mCurrentScreen + 1 )% getChildCount()
snapToScreen(bound, velocityX, true)
} else {
snapToScreen(whichScreen, 0, true)
}
/***********************************************/
//下面是原生代码
/*if (velocityX >SNAP_VELOCITY &&mCurrentScreen >0) {
// Fling hard enough to move left.
// Don't fling across more than one screen at a time.
final int bound = scrolledPos <whichScreen ?
mCurrentScreen - 1 : mCurrentScreen
snapToScreen(Math.min(whichScreen, bound), velocityX, true)
} else if (velocityX <-SNAP_VELOCITY &&mCurrentScreen <
getChildCount() - 1) {
// Fling hard enough to move right
// Don't fling across more than one screen at a time.
final int bound = scrolledPos >whichScreen ?
mCurrentScreen + 1 : mCurrentScreen
snapToScreen(Math.max(whichScreen, bound), velocityX, true)
} else {
snapToScreen(whichScreen, 0, true)
}*/
}
mTouchState = TOUCH_STATE_REST
mActivePointerId = INVALID_POINTER
releaseVelocityTracker()
break
那么就要在修改的地方加一个判断,如果system中取得的值是1,就可以循环,如果是0,就不能。
代码修改如下:
java代码
case MotionEvent.ACTION_UP:
if (mTouchState == TOUCH_STATE_SCROLLING) {
final VelocityTracker velocityTracker = mVelocityTracker
velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity)
final int velocityX = (int)
velocityTracker.getXVelocity(mActivePointerId)
final int screenWidth = getWidth()
final int whichScreen = (mScrollX + (screenWidth / 2)) / screenWidth
final float scrolledPos = (float) mScrollX / screenWidth
Log.i("velocityX","velocityX="+velocityX+"whichScreen="+whichScreen)
/***********************************************/
//modifided by xxnan 2013-1-9
launch_repeat=Settings.System.getInt(mContext.getContentResolver(),
"launch_repeat",0)//取出system表中“launch_repeat”的值
Log.i(" launch_repeat"," launch_repeat="+ launch_repeat)
if(launch_repeat==1)//如果是1,就循环,也就是之前已经改好的
{
if (velocityX >SNAP_VELOCITY) {
// Fling hard enough to move left.
// Don't fling across more than one screen at a time.
Log.i("numscreen","numscreen="+mCurrentScreen)
/* final int bound = scrolledPos <whichScreen ?
( (mCurrentScreen+ getChildCount()) - 1 )% getChildCount():
mCurrentScreen*/
final int bound =( (mCurrentScreen+ getChildCount()) - 1 )% getChildCount()
Log.i("numscreen","bound="+bound)
snapToScreen( bound, velocityX, true)
} else if (velocityX <-SNAP_VELOCITY ) {
// Fling hard enough to move right
// Don't fling across more than one screen at a time.
/*final int bound = scrolledPos >whichScreen ?
( mCurrentScreen + 1 )% getChildCount(): mCurrentScreen*/
final int bound = ( mCurrentScreen + 1 )% getChildCount()
snapToScreen(bound, velocityX, true)
} else {
snapToScreen(whichScreen, 0, true)
}
}
else//如果是0,那么就是原生代码,不循环
{
if (velocityX >SNAP_VELOCITY &&mCurrentScreen >0) {
// Fling hard enough to move left.
// Don't fling across more than one screen at a time.
final int bound = scrolledPos <whichScreen ?
mCurrentScreen - 1 : mCurrentScreen
snapToScreen(Math.min(whichScreen, bound), velocityX, true)
} else if (velocityX <-SNAP_VELOCITY &&mCurrentScreen <
getChildCount() - 1) {
// Fling hard enough to move right
// Don't fling across more than one screen at a time.
final int bound = scrolledPos >whichScreen ?
mCurrentScreen + 1 : mCurrentScreen
snapToScreen(Math.max(whichScreen, bound), velocityX, true)
} else {
snapToScreen(whichScreen, 0, true)
}
}
/***********************************************/
//下面是原生代码
/*if (velocityX >SNAP_VELOCITY &&mCurrentScreen >0) {
// Fling hard enough to move left.
// Don't fling across more than one screen at a time.
final int bound = scrolledPos <whichScreen ?
mCurrentScreen - 1 : mCurrentScreen
snapToScreen(Math.min(whichScreen, bound), velocityX, true)
} else if (velocityX <-SNAP_VELOCITY &&mCurrentScreen <
getChildCount() - 1) {
// Fling hard enough to move right
// Don't fling across more than one screen at a time.
final int bound = scrolledPos >whichScreen ?
mCurrentScreen + 1 : mCurrentScreen
snapToScreen(Math.max(whichScreen, bound), velocityX, true)
} else {
snapToScreen(whichScreen, 0, true)
}*/
}
mTouchState = TOUCH_STATE_REST
mActivePointerId = INVALID_POINTER
releaseVelocityTracker()
break
当然这里面也要定义几个量,以及导入几个包:
导入包:
//add by xxnan
import android.content.ContentResolver//从system表中取数据
import android.provider.Settings
定义变量:
private int launch_repeat//取得是否循环的值
到这里就全部修改好了,还有就是编译一下源码中的package/apps的Launch2和Settings的源码,将生成的out/target/。。。/system/app下的
Launch2.apk和Settings.apk替换手机里system/app的这两个apk就可以了。
这是跑马灯的效果。实现该功能步骤:
1、自定义Views,继承自TextView。
2、重写onDrow方法,计算每次的滚动的距离。
3、计算view的Y轴的重点,让当前显示的处于高亮显示状态。
4、定时的刷新View使其界面不断的刷先,出现滚动的效果。
5、实现数据结构,将数据传给view。
几个步骤代码可以参考下面
下面看看主要代码:1、创建一个类继承TextView
/**
* @author xushilin
*
* 垂直滚动的TextView Widget
*/
public class VerticalScrollTextView extends TextView
2、实现构造函数:
public VerticalScrollTextView(Context context) {
super(context)
init()
}
public VerticalScrollTextView(Context context, AttributeSet attr) {
super(context, attr)
init()
}
public VerticalScrollTextView(Context context, AttributeSet attr, int i) {
super(context, attr, i)
init()
}
private void init() {
setFocusable(true)
//这里主要处理如果没有传入内容显示的默认值
if(list==null){
list=new ArrayList<Notice>()
Notice sen=new Notice(0,"暂时没有通知公告")
list.add(0, sen)
}
//普通文字的字号,以及画笔颜色的设置
mPaint = new Paint()
mPaint.setAntiAlias(true)
mPaint.setTextSize(16)
mPaint.setColor(Color.BLACK)
mPaint.setTypeface(Typeface.SERIF)
//高亮文字的字号,以及画笔颜色的设置
mPathPaint = new Paint()
mPathPaint.setAntiAlias(true)
mPathPaint.setColor(Color.RED)
mPathPaint.setTextSize(16)
mPathPaint.setTypeface(Typeface.SANS_SERIF)
}
3、从写onDraw方法,并计算文字的行距,并且将将普通文字和高亮文字,在这个方法中绘制出来
protected void onDraw(Canvas canvas) {
super.onDraw(canvas)
canvas.drawColor(0xEFeffff)
Paint p = mPaint
Paint p2 = mPathPaint
p.setTextAlign(Paint.Align.CENTER)
if (index == -1)
return
p2.setTextAlign(Paint.Align.CENTER)
canvas.drawText(list.get(index).getName(), mX, middleY, p2)
float tempY = middleY
for (int i = index - 1 i >= 0 i--) {
tempY = tempY - DY
if (tempY < 0) {
break
}
canvas.drawText(list.get(i).getName(), mX, tempY, p)
}
tempY = middleY
for (int i = index + 1 i < list.size() i++) {
tempY = tempY + DY
if (tempY > mY) {
break
}
canvas.drawText(list.get(i).getName(), mX, tempY, p)
}
}
4、计算Y轴中值以及更新索引
protected void onSizeChanged(int w, int h, int ow, int oh) {
super.onSizeChanged(w, h, ow, oh)
mX = w * 0.5f
mY = h
middleY = h * 0.5f
}
private long updateIndex(int index) {
if (index == -1)
return -1
this.index=index
return index
}
5、定时更新view,并将接口暴露给客户程序调用。
public void updateUI(){
new Thread(new updateThread()).start()
}
class updateThread implements Runnable {
long time = 1000
int i=0
public void run() {
while (true) {
long sleeptime = updateIndex(i)
time += sleeptime
mHandler.post(mUpdateResults)
if (sleeptime == -1)
return
try {
Thread.sleep(time)
i++
if(i==getList().size())
i=0
} catch (InterruptedException e) {
e.printStackTrace()
}
}
}
}
Handler mHandler = new Handler()
Runnable mUpdateResults = new Runnable() {
public void run() {
invalidate()
}
}
6、xml布局文件中调用:
<?xml version="1.0" encoding="utf-8"?>
<!-- Demonstrates scrolling with a ScrollView. -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<com.demo.xsl.text.SampleView
android:id="@+id/sampleView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/selector"
/>
</LinearLayout>
7、java代码中调用,传递数据:
package com.demo.xsl.text
import java.util.ArrayList
import java.util.List
import android.app.Activity
import android.os.Bundle
import android.os.Handler
public class VerticalScrollTextActivity extends Activity {
SampleView mSampleView
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main)
mSampleView = (SampleView) findViewById(R.id.sampleView1)
List lst=new ArrayList<Sentence>()
for(int i=0i<30i++){
if(i%2==0){
Sentence sen=new Sentence(i,i+"、金球奖三甲揭晓 C罗梅西哈维入围 ")
lst.add(i, sen)
}else{
Sentence sen=new Sentence(i,i+"、公牛欲用三大主力换魔兽?????")
lst.add(i, sen)
}
}
//给View传递数据
mSampleView.setList(lst)
//更新View
mSampleView.updateUI()
}
}
在TextView中设置android:scrollHorizontally="true"
在Java中设置属性
textview.setMovementMethod(ScrollingMovementMethod.getInstance())
这样在铺满的时候就可以滚动了
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)