源码地址:https://github.com/ldy1993/ToolforAS.git
安卓的视图是建立在window之上。window上面有虚拟键,状态栏,软键盘,还有view。
/*举几个例子*/
//设置状态栏
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().setStatusBarColor(getResources().
getColor(R.color.yekuo_title));
}
//禁止系统软键盘主动弹出
getWindow().setSoftInputMode(WindowManager.LayoutParams.
SOFT_INPUT_STATE_ALWAYS_HIDDEN);
//以及设置屏幕常亮
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
//设置窗体全屏
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
view又有两个子类,控件View和容器ViewGroup。
控件View标识了一个一个的控件,容器ViewGroup里面可以包含多个控件view和多个容器ViewGroup。
ViewGroup通过实现两个接口:ViewParent 和 ViewManager创建view。
//1、activity的onCreate中创建了window。
//2、window创建了一个基础ViewGroup FrameLayout,然后实现了子类DecorView,
//3、也就是说DecorView是activity最顶层的view
//4、FrameLayout继承了application的ViewGroup,
//5、application下的theme代表了系统自带或者自定义的一种布局。一个activity如果没有用新的布局去覆盖将默认显示application上的view
//6、setContentView为window添加了view,添加了本activity的theme代表的样式
使用java中的方法定义view。
//1、activity的onCreate中创建了window。
//2、window创建了一个基础ViewGroup FrameLayout,然后实现了子类DecorView,
//3、也就是说DecorView是activity最顶层的view
//4、FrameLayout继承了application的ViewGroup,
//5、application下的theme代表了系统自带或者自定义的一种布局。如果没有用新的布局去覆盖将默认显示application上的view
super.onCreate(savedInstanceState);
//6、setContentView为window添加了view,添加了本activity的theme代表的样式
//setContentView(R.layout.activity_day5);
//7、使用java中的方法定义view,不是资源文件中的xml。
//接口 ViewParent:定义了成为一个View的parent的一些“职能”,当parent 和 它的child相互影响的时候查看此类。
ViewParent viewParent = (ViewParent) getWindow().getDecorView();
FrameLayout relativeLayout = (FrameLayout) viewParent;
Button button = new Button(this);
button.setText("一个按钮控件");
LinearLayout linearLayout=new LinearLayout(this);
//接口 ViewManager :在一个Activity中 add 或者 remove 一个 child view,通过Context.getSystemService()得到它的实例。
linearLayout.addView(button,300,200);
relativeLayout.addView(linearLayout);
使用资源文件里面的xml定义view。
对于setContentView,采用的是inflate,打气的方法,把资源文件打成view。
在frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindow.java中
protected ViewGroup generateLayout(DecorView decor) {
....
mDecor.startChanging();
View in = mLayoutInflater.inflate(layoutResource, null);
decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
...
return contentParent;
}
首先收集在清单配置文件中,给该activity配置的theme属性值,然后根据这些属性值去加载系统的布局文件,设置这些theme属性值也可以在代码中设置,不过要setContentView()之前,不过就不起作用了.
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">
<Button
android:id="@+id/bt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这是第二个button"/>
<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="这是第一条tv"
android:textSize="60dp"/>
</LinearLayout>
代码中
//第一种xml转换成view
setContentView(R.layout.activity_day5);
TextView tv=findViewById(R.id.tv);
Button bt=(Button) findViewById(R.id.bt);
bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(Day5_Activity.this, "按钮被点击了", Toast.LENGTH_LONG).show();
}
});
tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(Day5_Activity.this, "tv被点击了", Toast.LENGTH_LONG).show();
}
});
//第二种xml转换成view
LayoutInflater layoutInflater = (LayoutInflater)
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// 其实第一种就是第二种的简单写法,只是Android给我们做了一下封装而已。得到了LayoutInflater的实例之后就可以调用它的inflate()方法来加载布局了,如下所示:
layoutInflater.inflate(R.layout.activity_day5, null);
这样就可以生成两个点击事件的界面了。
下附一幅window窗口下的布局图
下一节:
3.4、视图view_自定义控件