在launcher3里的launcher.xml
去掉搜索栏
packages\apps\Launcher3\src\com\android\launcher3\Launcher.java
public View getQsbBar() {
if (mQsbBar == null) {
mQsbBar = mInflater.inflate(R.layout.search_bar, mSearchDropTargetBar, false);
//mSearchDropTargetBar.addView(mQsbBar);
}
return mQsbBar;
}
//mSearchDropTargetBar.addView(mQsbBar);隐藏掉
launcher.xml是FrameLayout布局
在FrameLayout布局里,定义任何空间的位置相关的属性都毫无意义。控件自动的堆放在左上角,根本不听你的控制。
FrameLayout根本无法控制他的子控件的位置。所有的控件都是左上对其。但是控件本身是可以控制自己内部的布局的。
所以
android:layout_width="match_parent"
android:layout_height="match_parent"
用android:gravity="bottom"在自身内部的布局。
而
android:layout_width="wrap_content"
android:layout_height="wrap_content"
是没有作用的。
添加Textview
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom"
android:text="@string/all_apps_cling_title" />
launcher.xml
比如 我想显示0~100动态显示。
public void showTemparetrue() {
new Thread() {
int cnt = 0;
@Override
public void run() {
while(true){
try {
cnt++;
//mTemparetrue.setText("80");
//mTemparetrue.setTextColor(0xffff00ff);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
这样是会报错异常的
E/AndroidRuntime( 6699): FATAL EXCEPTION: Thread-653
E/AndroidRuntime( 6699): Process: com.android.launcher3, PID: 6699
E/AndroidRuntime( 6699): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy ca
n touch its views.
E/AndroidRuntime( 6699): at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6174)
E/AndroidRuntime( 6699): at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:862)
E/AndroidRuntime( 6699): at android.view.ViewGroup.invalidateChild(ViewGroup.java:4320)
E/AndroidRuntime( 6699): at android.view.View.invalidate(View.java:10940)
E/AndroidRuntime( 6699): at android.view.View.invalidate(View.java:10895)
E/AndroidRuntime( 6699): at android.widget.TextView.checkForRelayout(TextView.java:6587)
E/AndroidRuntime( 6699): at android.widget.TextView.setText(TextView.java:3813)
E/AndroidRuntime( 6699): at android.widget.TextView.setText(TextView.java:3671)
E/AndroidRuntime( 6699): at android.widget.TextView.setText(TextView.java:3646)
E/AndroidRuntime( 6699): at com.android.launcher3.Launcher$41.run(Launcher.java:4531)
W/ActivityManager( 468): Force finishing activity com.android.launcher3/.Launcher
I/ActivityManager( 468): START u0 {act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000000 cmp=com.android.launche
r3/.Launcher} from pid 0
原因:
在android平台下,进行多线程编程时,经常需要在主线程之外的一个单独的线程中进行某些处理,然后更新用户界面显示。但是,在主线线程之外的线程中直接更新页面显示的问题是:系统会报这个异常,android.view.viewroot$calledfromwrongthreadexception: only the original thread that created a view hierarchy can touch its views. (只有原始创建这个视图层次(view hierachy)的线程才能修改它的视图(view)。)。也就是说必须在程序的主线程(也就是ui线程)中进行更新界面显示的工作。
解决方案:在activity.oncreate(bundle savedinstancestate)中创建一个handler类的实例, 在这个handler实例的handlemessage回调函数中调用更新界面显示的函数。
public void showTemparetrue() {
new Thread() {
//int cnt = 0;
@Override
public void run() {
//boolean success = true;
while(true){
try {
//cnt++;
//mTemparetrue.setText("80");
//mTemparetrue.setTextColor(0xffff00ff);
Message msg = mHandler.obtainMessage(TEMP_MSG); //private final int TEMP_MSG = 100;
mHandler.sendMessageDelayed(msg, 100);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if(msg.what == TEMP_MSG){
TEMP_current++;
if(TEMP_current > 70){
mTemparetrue.setTextColor(0xffff00ff);
}else{
mTemparetrue.setTextColor(0xffff0033);
}
if(TEMP_current > 80){
TEMP_current = 50;
}
String s = String.valueOf( TEMP_current);
mTemparetrue.setText(getString(R.string.settings_temperature_text, s));
// <string name="settings_temperature_text">%s°C</string>
}
@Override
public void onDestroy() {
super.onDestroy();
// Remove all pending runnables
mHandler.removeMessages(TEMP_MSG);
}
参考 :http://blog.csdn.net/vincent_czz/article/details/7070354