android層級
Ⅰ 聽說蘋果比安卓快是因為響應層級不同。那請問安卓的響應層級順序是什麼
是的,樓主你說的沒錯。Android系統的優先順序響應層級則是Application--Framework--Library--Kernal架構。相比起蘋果第三道第三層才能到屏幕上反應,所以在流暢度上蘋果確實勝過安卓
Ⅱ android打造任意層級的樹形控制項那個id能不能用string
由於整體比較長,我決定首先帶大家看一下用法,就是如果學完了這篇博客,我們需要樹形控制項,我們需要花多少精力去完成~~
現在需求來了:我現在需要展示一個文件管理系統的樹形結構:
數據是這樣的:
//id , pid , label , 其他屬性
mDatas.add(new FileBean(1, 0, "文件管理系統"));
mDatas.add(new FileBean(2, 1, "游戲"));
mDatas.add(new FileBean(3, 1, "文檔"));
mDatas.add(new FileBean(4, 1, "程序"));
mDatas.add(new FileBean(5, 2, "war3"));
mDatas.add(new FileBean(6, 2, "刀塔傳奇"));
mDatas.add(new FileBean(7, 4, "面向對象"));
mDatas.add(new FileBean(8, 4, "非面向對象"));
mDatas.add(new FileBean(9, 7, "C++"));
mDatas.add(new FileBean(10, 7, "java"));
mDatas.add(new FileBean(11, 7, "Javascript"));
mDatas.add(new FileBean(12, 8, "C"));
當然了,bean可以有很多屬性,我們提供你動態的設置樹節點上的顯示、以及不約束id, pid 的命名,你可以起任意喪心病狂的屬性名稱;
那麼我們如何確定呢?
看下Bean:
package com.zhy.bean;
import com.zhy.tree.bean.TreeNodeId;
import com.zhy.tree.bean.TreeNodeLabel;
import com.zhy.tree.bean.TreeNodePid;
public class FileBean
{
@TreeNodeId
private int _id;
@TreeNodePid
private int parentId;
@TreeNodeLabel
private String name;
private long length;
private String desc;
public FileBean(int _id, int parentId, String name)
{
super();
this._id = _id;
this.parentId = parentId;
this.name = name;
}
}
現在,不用說,應該也知道我們通過註解來確定的。
下面看我們如何將這數據轉化為樹
布局文件就一個listview,就補貼了,直接看Activity
package com.zhy.tree_view;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
import com.zhy.bean.FileBean;
import com.zhy.tree.bean.TreeListViewAdapter;
public class MainActivity extends Activity
{
private List<FileBean> mDatas = new ArrayList<FileBean>();
private ListView mTree;
private TreeListViewAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initDatas();
mTree = (ListView) findViewById(R.id.id_tree);
try
{
mAdapter = new SimpleTreeAdapter<FileBean>(mTree, this, mDatas, 10);
mTree.setAdapter(mAdapter);
} catch (IllegalAccessException e)
{
e.printStackTrace();
}
}
private void initDatas()
{
// id , pid , label , 其他屬性
mDatas.add(new FileBean(1, 0, "文件管理系統"));
mDatas.add(new FileBean(2, 1, "游戲"));
mDatas.add(new FileBean(3, 1, "文檔"));
mDatas.add(new FileBean(4, 1, "程序"));
mDatas.add(new FileBean(5, 2, "war3"));
mDatas.add(new FileBean(6, 2, "刀塔傳奇"));
mDatas.add(new FileBean(7, 4, "面向對象"));
mDatas.add(new FileBean(8, 4, "非面向對象"));
mDatas.add(new FileBean(9, 7, "C++"));
mDatas.add(new FileBean(10, 7, "JAVA"));
mDatas.add(new FileBean(11, 7, "Javascript"));
mDatas.add(new FileBean(12, 8, "C"));
}
}
Activity裡面並沒有什麼特殊的代碼,拿到listview,傳入mData,當中初始化了一個Adapter;
看來我們的核心代碼都在我們的Adapter裡面:
那麼看一眼我們的Adapter
package com.zhy.tree_view;
import java.util.List;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import com.zhy.tree.bean.Node;
import com.zhy.tree.bean.TreeListViewAdapter;
public class SimpleTreeAdapter<T> extends TreeListViewAdapter<T>
{
public SimpleTreeAdapter(ListView mTree, Context context, List<T> datas,
int defaultExpandLevel) throws IllegalArgumentException,
IllegalAccessException
{
super(mTree, context, datas, defaultExpandLevel);
}
@Override
public View getConvertView(Node node , int position, View convertView, ViewGroup parent)
{
ViewHolder viewHolder = null;
if (convertView == null)
{
convertView = mInflater.inflate(R.layout.list_item, parent, false);
viewHolder = new ViewHolder();
viewHolder.icon = (ImageView) convertView
.findViewById(R.id.id_treenode_icon);
viewHolder.label = (TextView) convertView
.findViewById(R.id.id_treenode_label);
convertView.setTag(viewHolder);
} else
{
viewHolder = (ViewHolder) convertView.getTag();
}
if (node.getIcon() == -1)
{
viewHolder.icon.setVisibility(View.INVISIBLE);
} else
{
viewHolder.icon.setVisibility(View.VISIBLE);
viewHolder.icon.setImageResource(node.getIcon());
}
viewHolder.label.setText(node.getName());
return convertView;
}
private final class ViewHolder
{
ImageView icon;
TextView label;
}
}
我們的SimpleTreeAdapter繼承了我們的TreeListViewAdapter ; 除此之外,代碼上只需要復寫getConvertView , 且getConvetView其實和我們平時的getView寫法一致;
公布出getConvertView 的目的是,讓用戶自己去決定Item的展示效果。其他的代碼,我已經打包成jar了,用的時候導入即可。這樣就完成了我們的樹形控制項。
也就是說用我們的樹形控制項,只需要將傳統繼承BaseAdapter改為我們的TreeListViewAdapter ,然後去實現getConvertView 就好了。
Ⅲ Android 在java層里有沒有辦法控制多個SurfaceView之間的層級關系
完整答案,需要點兒耐心看哦。
有不少朋友都遇到過這種問題,程序執行時切換到後台,然後再重新進入會報異常,本文就這種問題全面講解下SurfaceView的運行機制,了解了這些原理你就能自己解決這些問題了。
我們通常會通過單擊HOME按鍵或返回按鍵等操作切換到後台,之後可能會再次進入程序,這個時候就有可能報異常。這里SurfaceView可能報的異常主要有兩點,如下:
一、提交畫布異常。如下圖(模擬器錯誤提示,以及Logcat Detail)
Java代碼
public void draw() {
try {
canvas = sfh.lockCanvas();
if (canvas != null) {
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(bmp, bmp_x, bmp_y, paint);
}
} catch (Exception e) {
Log.v("Himi", "draw is Error!");
} finally {//備注1
if (canvas != null)//備注2
sfh.unlockCanvasAndPost(canvas);
}
}
先看備注1這里,之前的文章中我給大家解釋過為什麼要把 sfh.unlockCanvasAndPost(canvas); 寫在finally中,主要是為了保證能正常的提交畫布。
今天主要說說備注2,這里一定要判定下canvas是否為空,因為當程序切入後台的時候,canvas是獲取不到的!那麼canvas一旦為空,提交畫布這里就會出現參數異常的錯誤!
二、線程啟動異常。如下圖(模擬器錯誤提示,以及Logcat Detail)
這種異常只是在當你程序運行期間點擊Home按鈕後再次進入程序的時候報的異常,異常說咱們的線程已經啟動!為什麼返回按鈕就沒事?
OK,下面我們就要來先詳細講解一下Android中Back和Home按鍵的機制!然後分析問題,並且解決問題!
先看下面MySurfaceViewAnimation.java的類中的代碼:
Java代碼
public class MySurfaceViewAnimation extends SurfaceView implements Callback, Runnable {
private Thread th;
private SurfaceHolder sfh;
private Canvas canvas;
private Paint paint;
private Bitmap bmp;
private int bmp_x, bmp_y;
public MySurfaceViewAnimation(Context context) {
super(context);
this.setKeepScreenOn(true);
bmp = BitmapFactory.decodeResource(getResources(), R.drawable.himi_dream);
sfh = this.getHolder();
sfh.addCallback(this);
paint = new Paint();
paint.setAntiAlias(true);
this.setLongClickable(true);
th = new Thread(this, "himi_Thread_one");
Log.e("Himi", "MySurfaceViewAnimation");
}
public void surfaceCreated(SurfaceHolder holder) {
th.start();
Log.e("Himi", "surfaceCreated");
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Log.e("Himi", "surfaceChanged");
}
public void surfaceDestroyed(SurfaceHolder holder) {
Log.e("Himi", "surfaceDestroyed");
}
public void draw() {
try {
canvas = sfh.lockCanvas();
if (canvas != null) {
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(bmp, bmp_x, bmp_y, paint);
}
} catch (Exception e) {
Log.v("Himi", "draw is Error!");
} finally {//備注1
if (canvas != null)//備注2
sfh.unlockCanvasAndPost(canvas);
}
}
public void run() {
while (true) {
draw();
try {
Thread.sleep(100);
} catch (Exception ex) {
}
}
}
}
以上是我們常用的自定義SurfaceView,並且使用Runnable介面老框架了不多說了,其中我在本類的構造、創建、狀態改變、消亡函數都加上列印!
OK,下面看第一張圖:(剛運行程序)
上圖的左邊部分是Dubug。這里顯示我們有一條線程在運行,名字叫」himi_Thread_one」。
上圖的右邊部分是LogCat日誌。大家很清晰的看到,當第一次進入程序的時候,會先進入view構造函數、然後是創建view,然後是view狀態改變,OK,這個大家都知道!
下面是我來點擊Home(手機上的小房子)按鍵,這時程序處於後台,然後重新進入程序的過程!
上圖可以看出我們的線程還是一條,這里主要觀察從點擊home到再次進入程序的過程,如下所述:
點擊home 調用了view銷毀,然後進入程序會先進入view創建,最後是view狀態改變。
上面的過程很容易理解,重要的角色上場了~Back 按鈕!點我點擊Back按鈕看看發生了什麼!
先看左邊的Debug一欄,多了一條線程! 看LogCat發現比點擊Home按鍵多調用了一次構造函數!
好了,從我們測試的程序來看,無疑,點擊Home 和 點擊 Back按鈕再次進入程序的時候,步驟是不一樣的,線程數量也變了!
那麼這里就能解釋為什麼我們點擊Back按鈕不異常,點擊Home會異常了!
原因:因為點擊Back按鈕再次進入程序的時候先進入的是view構造函數里,那麼就是說這里又new了一個線程出來,並啟動!那麼而我們點擊Home卻不一樣了,因為點擊home之後再次進入程序不會進入構造函數,而是直接進入了view創建這個函數,而在view創建這個函數中我們有個啟動線程的操作,其實第一次啟動程序的線程還在運行,so~這里就一定異常了,說線程已經啟動!
有些童鞋會問,我們為何不把th = new Thread(this, 「himi_Thread_one」);放在view創建函數中不就好了?!
沒錯,可以!但是當你反復幾次之後你發現你的程序中會多出很多條進程!(如下圖)
雖然可以避免出現線程已經啟動的異常,很明顯這不是我們想要的結果!
那麼下面給大家介紹最合適的解決方案:
修改MySurfaceViewAnimation.java:
Java代碼
public class MySurfaceViewAnimation extends SurfaceView implements Callback, Runnable {
private Thread th;
private SurfaceHolder sfh;
private Canvas canvas;
private Paint paint;
private Bitmap bmp;
private int bmp_x, bmp_y;
private boolean himi; //備注1
public MySurfaceViewAnimation(Context context) {
super(context);
this.setKeepScreenOn(true);
bmp = BitmapFactory.decodeResource(getResources(), R.drawable.himi_dream);
sfh = this.getHolder();
sfh.addCallback(this);
paint = new Paint();
paint.setAntiAlias(true);
this.setLongClickable(true);
Log.e("Himi", "MySurfaceViewAnimation");
}
public void surfaceCreated(SurfaceHolder holder) {
himi = true;
th = new Thread(this, "himi_Thread_one");//備注2
th.start();
Log.e("Himi", "surfaceCreated");
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Log.e("Himi", "surfaceChanged");
}
public void surfaceDestroyed(SurfaceHolder holder) {
himi = false;//備注3
Log.e("Himi", "surfaceDestroyed");
}
public void draw() {
try {
canvas = sfh.lockCanvas();
if (canvas != null) {
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(bmp, bmp_x, bmp_y, paint);
}
} catch (Exception e) {
Log.v("Himi", "draw is Error!");
} finally {
if (canvas != null)
sfh.unlockCanvasAndPost(canvas);
}
}
public void run() {
while (himi) {//備注4
draw();
try {
Thread.sleep(100);
} catch (Exception ex) {
}
}
}
}
這里修改的地方有以下幾點:
1、我們都知道一個線程啟動後,只要run方法執行結束,線程就銷毀了,所以我增加了一個布爾值的成員變數 himi(備注1),這里可以控制我們的線程消亡的一個開關!(備注4)
2、在啟動線程之前,設置這個布爾值為ture,讓線程一直運行。
3、在view銷毀時,設置這個布爾值為false,銷毀當前線程!(備注3)
OK,這里圖和解釋夠詳細了,希望大家以後真正開發一款游戲的時候,一定要嚴謹代碼,不要留有後患哈~
Ⅳ android 怎麼計算一個view的嵌套層級
層級關系的布局有兩種解決方法:
一種方法是使用標簽的自然順序和嵌套順序來形成合理的布局。
而第一種方法卻不是萬能的,有時候我們需要將原本位於下層的元素移到另一個元素上方,那可以使用z-index;
而你說的不好用,則是zindex沒有生效,沒生效就是沒有定義position屬性,如果不想讓元素的位置有所變化,就給賦予z-index屬性的元素加上相對定位的position:relative;
Ⅳ android如何動態改變控制項的層級(疊放層次)
在左邊圖的基礎上增加如右圖控制項b的控制項c,然後控制控制項c的顯示與隱藏
Ⅵ Android系統分成哪4個層次:
對的 你理解的是對的啊,這是android開發的四個層次
Ⅶ 安卓開發:如何設置控制項疊放的層次
只需要在布局文件中調整代碼位置,你想把什麼放界面的最上面就把代碼放在xml文件的最下面,這樣的順序。
Ⅷ android應用界面中ui組件間有嚴格的層次關系,有哪兩種類型的視圖
不明白,安卓常用的布局方式有相對布局,線性布局,絕對布局和表格布局等,其中絕對布局和相對布局後添加的組件可把先添加的組件覆蓋掉,不知道是不是題主需要的。
Ⅸ android 現在很火 ,但我不知道android定位在什麼層次的,
從入門到低端再到中端甚至高端都有涉及
軟體都是涉及硬體的......
專業性很強
做網站看你做什麼網站了(這方面本人小白 畢竟您把問題放到了手機購買這個分類里.....)
Ⅹ android設置dialog在第幾層顯示
android中dialog都是彈出的對話框,沒有第幾層這個概念,只有dialog有級別。
具體實現代碼:
1.創建對象框
AlertDialog.Builder builder = new Builder(context);
builder.setTitle("請輸入"); //設置對話框標題
builder.setIcon(android.R.drawable.btn_star); //設置對話框標題前的圖標
2.創建EditText輸入框
final EditText edit = new EditText(context);
3.將輸入框賦值給Dialog,並增加確定取消按鍵
builder.setView(edit);
builder.setPositiveButton("確認", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(context, "你輸入的是: " + edit.getText().toString(), Toast.LENGTH_SHORT).show();
}
});
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(context, "你點了取消", Toast.LENGTH_SHORT).show();
}
});
4.設置常用api,並show彈出
builder.setCancelable(true); //設置按鈕是否可以按返回鍵取消,false則不可以取消
AlertDialog dialog = builder.create(); //創建對話框
dialog.setCanceledOnTouchOutside(true); //設置彈出框失去焦點是否隱藏,即點擊屏蔽其它地方是否隱藏
dialog.show();