导航:首页 > 操作系统 > androidxmlnstools

androidxmlnstools

发布时间:2022-08-19 00:54:16

A. 安卓xml布局。重合在一起。

相对布局本来就是这样,你没有指明它们之间的相对位置,它们只能按照原始位置摆放,
RelativeLayout改成LinerLayout就不会了

B. android系统如何调用自带的相机相册

LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="gallery"
android:text="获取图库图片" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="camera"
android:text="拍照获取图片" />

<ImageView
android:id="@+id/iv_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>

//------------------我的MainActivity --------------也很简单--------------------------

package tackpicture.bwie.com.tackpicture;

import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;

import java.io.File;

public class MainActivity extends AppCompatActivity {

private ImageView iv_image;

private static final int PHOTO_REQUEST_CAREMA = 1;// 拍照
private static final int PHOTO_REQUEST_GALLERY = 2;// 从相册中选择
private static final int PHOTO_REQUEST_CUT = 3;// 结果
/* 头像名称 */
private static final String PHOTO_FILE_NAME = "temp_photo.jpg";
private File tempFile;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//找到控件
iv_image = (ImageView) findViewById(R.id.iv_image);
}

//图库
public void camera(View view) {
// 激活系统图库,选择一张图片
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
// 开启一个带有返回值的Activity,请求码为PHOTO_REQUEST_GALLERY
startActivityForResult(intent, PHOTO_REQUEST_GALLERY);
}

//相机
public void gallery(View view) {
// 激活相机
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
// 判断存储卡是否可以用,可用进行存储
if (hasSdcard()) {
tempFile = new File(Environment.getExternalStorageDirectory(), PHOTO_FILE_NAME);
// 从文件中创建uri
Uri uri = Uri.fromFile(tempFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
}
// 开启一个带有返回值的Activity,请求码为PHOTO_REQUEST_CAREMA
startActivityForResult(intent, PHOTO_REQUEST_CAREMA);
}

/*
* 剪切图片
*/
private void crop(Uri uri) {
// 裁剪图片意图
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
intent.putExtra("crop", "true");
// 裁剪框的比例,1:1
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
// 裁剪后输出图片的尺寸大小
intent.putExtra("outputX", 250);
intent.putExtra("outputY", 250);

intent.putExtra("outputFormat", "JPEG");// 图片格式
intent.putExtra("noFaceDetection", true);// 取消人脸识别
intent.putExtra("return-data", true);
// 开启一个带有返回值的Activity,请求码为PHOTO_REQUEST_CUT
startActivityForResult(intent, PHOTO_REQUEST_CUT);
}

/*
* 判断sdcard是否被挂载
*/
private boolean hasSdcard() {
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
return true;
} else {
return false;
}
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PHOTO_REQUEST_GALLERY) {
// 从相册返回的数据
if (data != null) {
// 得到图片的全路径
Uri uri = data.getData();
crop(uri);
}
} else if (requestCode == PHOTO_REQUEST_CAREMA) {
// 从相机返回的数据
if (hasSdcard()) {
crop(Uri.fromFile(tempFile));
} else {
Toast.makeText(MainActivity.this, "未找到存储卡,无法存储照片!", 0).show();
}

} else if (requestCode == PHOTO_REQUEST_CUT) {
// 从剪切图片返回的数据
if (data != null) {
Bitmap bitmap = data.getParcelableExtra("data");
this.iv_image.setImageBitmap(bitmap);
}
try {
// 将临时文件删除
tempFile.delete();
} catch (Exception e) {
e.printStackTrace();
}

}

super.onActivityResult(requestCode, resultCode, data);
}

}

C. android自定义shape 时xmlns怎么自动

MainActivity如下:
package cn.testshape;
import android.os.Bundle;
import android.app.Activity;
/**
* Demo描述:
* 自定义shape的使用
*/
public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}

}

main.xml如下:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
>

<Button
android:layout_width="250dip"
android:layout_height="50dip"
android:text="测试自定义shape的使用"
android:background="@drawable/background_selector"
android:textColor="@drawable/textcolor_selector"
android:layout_centerInParent="true"
android:gravity="center"
/>

</RelativeLayout>

background_selector.xml如下:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="@drawable/pressed_shape" android:state_pressed="true"/>
<item android:drawable="@drawable/default_shape"/>
</selector>

default_shape.xml如下:
<?xml version="1.0" encoding="utf-8"?>
<!-- 定义矩形rectangle -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<!-- 定义边框颜色 -->
<solid android:color="#d1d1d1" />
<!-- 定义圆角弧度 -->
<corners
android:bottomLeftRadius="4dp"
android:bottomRightRadius="4dp"
android:topLeftRadius="4dp"
android:topRightRadius="4dp"
/>

</shape>

pressed_shape.xml如下:
<?xml version="1.0" encoding="utf-8"?>
<!-- 定义矩形rectangle -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<!-- 定义边框颜色 -->
<solid android:color="#7bb3f8" />
<!-- 定义圆角弧度 -->
<corners
android:bottomLeftRadius="4dp"
android:bottomRightRadius="4dp"
android:topLeftRadius="4dp"
android:topRightRadius="4dp"
/>

</shape>

textcolor_selector.xml如下:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:color="#ffffff" android:state_pressed="true"/>
<item android:color="#000000"/>
</selector>

D. 如何理解Android中的xmlns

首先,我们先来看下到底什么是xmlns,它是 XML 文档中的一个概念:英文叫做 XML namespace,中文翻译为 XML 命名空间。一讲到命名空间,我想很多人会联想到C++中的namespace和Java中的 packagename,而这两者的作用都是为了解决命名上的冲突(例如类名,接口名等)。类似的,XML namespace也是为了解决 XML 中元素和属性命名冲突,因为 XML 中的标签并不是预定义的,这一点与 HTML 是有区别的,HTML 中的标签是预定义的,所以我们会遇到命名冲突的问题。

XML 命名空间定义语法为xmlns:namespace-prefix="namespaceURI",一共分为三个部分:

xmlns:声明命名空间的保留字,其实就是XML中元素的一个属性;

namespace-prefix:命名空间的前缀,这个前缀与某个命名空间相关联;

namespaceURI:命名空间的唯一标识符,一般就是一个URI引用。

通过上面的内容的讲解,我们对命名空间有了一定的了解,下面我们通过一个例子引用来说明一下xmlns属性是如何解决命名冲突的:

命名冲突
在 XML 中,元素名称是由开发者定义的,当两个不同的文档使用相同的元素名时,就会发生命名冲突。这个 XML 文档携带着某个表格中的信息:

<table>
<tr>
<td>Apples</td>
<td>Bananas</td>
</tr>
</table>

这个 XML 文档携带有关桌子的信息:

<table>
<name>African Coffee Table</name>
<width>80</width>
<length>120</length>
</table>

假如这两个 XML 文档被一起使用,由于两个文档都包含带有不同内容和定义的 <table> 元素,就会发生命名冲突。XML 解析器无法确定如何处理这类冲突。

使用命名空间(Namespace)
这个XML文档携带着某个表格中的信息:

<h:table xmlns:h="http://www.w3.org/TR/html4/">
<h:tr>
<h:td>Apples</h:td>
<h:td>Bananas</h:td>
</h:tr>
</h:table>

此XML文档携带着有关一件家具的信息:

<f:table xmlns:f="http://www.w3school.com.cn/furniture">
<f:name>African Coffee Table</f:name>
<f:width>80</f:width>
<f:length>120</f:length>
</f:table>

我们为<table>标签添加了一个xmlns属性,并在每个标签前面都添加了相应的前缀,这个前缀是一个与某个命名空间相关联的限定名称,这个前缀就代表后面那个 URI 引用,或者说一个缩写。

关于xmlns就先简单讲到这里,大家如果要深入了解的话,可以点击本文中的跳转链接,下一节我们来看下 Android 中的那些xmlns。

Android中的xmlns

在Android中,目前我们碰到的xmlns一共有三种:

xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"

android

命名空间android用于 Android 系统定义的一些属性。

app

命名空间app用于我们应用自定义的一些属性,这个与 Android 自定义属性和系统控件扩展应该有关系,大家可以再继续研究一下。

tools

根据官方定义,tools命名空间用于在 XML 文档记录一些,当应用打包的时候,会把这部分信息给过滤掉,不会增加应用的 size,说直白点,这些属性是为IDE提供相关信息

E. android怎么根据路径打开文件夹

Android根据路径打开文件夹的步骤:
1、android系统内置了很多应用,包括电话拨号,短信,浏览器等,这里创建一个简单的Android程序,调用内置的浏览器打开指定的地址。
2、对应的layout xml为:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="@+id/btnGo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginTop="46dp"
android:text="@string/btnTitle_go" />
<EditText
android:id="@+id/txtUri"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/btnGo"
android:layout_alignBottom="@+id/btnGo"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="@+id/btnGo"
android:ems="10"
android:text="http://junqilian.cnblogs.com" >
<requestFocus />
</EditText>
</RelativeLayout>
3、Java代码实现如下,主要是给EditText添加一个OnKeyListener,处理在editText里面按回车键,给button添加一个onClickListener,触发到OpenBroswer函数,通过intent打开内置的浏览器。

F. Android中如何在布局文件中为组件绑定点击事件

在Android中为组件绑定点击事件的方式可以分为四种,
1、 在xml布局文件中,定义onclick的方式
<!—第一步在XML文件中给对应组件添加Onclick属性-->
<Button
android:id="@+id/submitbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:onClick="buttonClickHandle"
android:layout_alignParentTop="true"
android:text="提交" />
//第二步在对应的Activity中创建一个与onClick属性值相同的方法,并传入一个View参数,当Button被点击时就会回调这个方法。
public void buttonClickHandle(View view) {
Snackbar.make(coordinatorLayout, "你点击了Button", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
另外三种绑定点击事件的方式实际上就是通过组件调用setOnClickListener()的方法,下面我们就来看一下这个方法的源码
/**
* Register a callback to be invoked when this view is clicked. If this view is not
* clickable, it becomes clickable.
*
* @param l The callback that will run
*
* @see #setClickable(boolean)
*/
public void setOnClickListener(@Nullable OnClickListener l) {
if (!isClickable()) {
setClickable(true);
}
getListenerInfo().mOnClickListener = l;
}

根据源码我们可以看到这个方法中需要一个OnClickListener的对象。下面我们就来看看这个OnClickListener对象是个什么东东。
/**
* Interface definition for a callback to be invoked when a view is clicked.
*/
public interface OnClickListener {
/**
* Called when a view has been clicked.
*
* @param v The view that was clicked.
*/
void onClick(View v);
}
根据源码我们可以看到实际上这个OnClickListener就是一个接口,这个接口中有一个onClick的抽象方法。所以我们在创建这个OnClickListener对象是还需要实现这个抽象方法。这个onClick的抽象方法实际上就是当我们点击按钮后会回调的方法。我们对于点击事件的响应处理就在这个方法中进行。
现在我们已经了解了设置点击事件的setOnClickListener方法,根据我们如何创建这个方法中的OnClickListener对象,我们设置点击事件的方式可以分为如下三种:
1、内部类的形式
a. package com.example.hsport.catalog;

import android.os.Bundle;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

private CoordinatorLayout coordinatorLayout;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
coordinatorLayout = (CoordinatorLayout) findViewById(R.id.coordinator);
// 获取button对象
Button button = (Button) findViewById(R.id.submitbutton);
//创建内部类的实例
MyListener myListener = new MyListener();
//设置button的点击事件,将实现OnClickListener接口的内部类实例传入到setOnClickListener方法中
button.setOnClickListener(myListener);
}

//创建一个内部类实现View.OnClickListener接口,并实现其onClick方法
private class MyListener implements View.OnClickListener {
@Override
public void onClick(View v) {
Snackbar.make(coordinatorLayout, "你点击了Button", Snackbar.LENGTH_LONG).setAction("Action", null).show();
}
}
}

2、 匿名内部类的方式
package com.example.hsport.catalog;

import android.os.Bundle;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

private CoordinatorLayout coordinatorLayout;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
coordinatorLayout = (CoordinatorLayout) findViewById(R.id.coordinator);
//获取Button对象
Button button = (Button) findViewById(R.id.submitbutton);
//以创建一个View.OnClickListener的匿名内部类,并实现它的onClick方法
button.setOnClickListener(new View.OnClickListener() {
//在onClick方法中我们就可以设置button的响应代码了
@Override
public void onClick(View v) {
Snackbar.make(coordinatorLayout, "你点击了Button",Snackbar.LENGTH_LONG).setAction("Action", null).show();
}
});
}

3、 让主类实现OnClickListener接口,然后再主类实现未实现的方法

package com.example.hsport.catalog;

import android.os.Bundle;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

private CoordinatorLayout coordinatorLayout;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
coordinatorLayout = (CoordinatorLayout) findViewById(R.id.coordinator);
//获取Button对象
Button button = (Button) findViewById(R.id.submitbutton);
//因为我们让MainActivity实现了View.OnClickListener这个接口,所以setOnClickListener方法中的参数直接传入this即可。
button.setOnClickListener(this);
}

//因为MainActivity实现了View.OnClickListener接口,所以在MainActivity中还有要实现该接口中改的onClick方法来处理点击事件。
@Override
public void onClick(View v) {
Snackbar.make(coordinatorLayout, "你点击了Button",Snackbar.LENGTH_LONG).setAction("Action", null).show();
}
}
关于如何给组件绑定点击事件,是Android中的基础知识,如果你还想更加详细的了解,推荐你可以去一个叫做秒秒学的教程网站看看,夯实下基础。

G. 如何在Android上开发属于自己的定制化启动器

从最基本的概念角度来讲,启动器其实应该是一款能够实现以下功能的应用程序:

它代表着一台设备的主屏幕。
它能够列出并启动已经安装在该设备当中的应用程序。

换句话来说,它就是那款用户按下home按钮后所显示的应用程序。除非大家已经安装了定制化启动器,否则我们目前正在使用的应该都是Android系统自带的默认启动方案。不少设备制造商都会在产品中默认使用由其定制的启动器,从而确保我们获得与厂商预期相符的外观效果与使用感受,例如三星TouchWiz以及HTC
Sense。

在今天的教程中,我们将利用基本用户界面创建出一款简单的启动器,它将由两部分屏幕构成:

在主屏幕中显示的是该设备的墙纸图案。
另一屏幕中显示的是已经安装在设备当中的应用程序图标及其它细节信息。

1.要求

大家需要在自己的开发设备上预先安装并配置好以下项目:

Android SDK以及平台工具
Eclipse IDE 3.7.2或者更高版本,同时具备ADT插件
运行有Android 2.2或者更高版本的模拟器或者Android设备

大家可以点击此处通过Android开发者门户下载对应SDK及平台工具。

2.项目设置

首先我们需要启动Eclipse并创建一个新的Android应用程序项目。我为这个应用取了个非常直白的名称——SimpleLauncher,当然大家也可以自由选择自己想要的名称。请确保软件包名称没有与其它项目出现重复。我们的启动器所能支持的最低SDK版本为“冻酸奶”,而主要的面向版本则为“果冻豆”。

由于我们不打算创建Activity,因此取消“Create Activity”勾选项,然后点击“Finish”以继续。

3.项目清单

接下来我们需要通过添加两个activity对AndroidManifest.xml文件进行修改。第一个Activity用于显示主屏幕,我们如下所示将其命名为HomeActivity。
<activity android:name="ah.hathi.simplelauncher.HomeActivity" android:label="Simple Launcher Home" android:theme="@android:style/Theme.Wallpaper.NoTitleBar.Fullscreen" android:launchMode="singleTask" android:stateNotNeeded="true" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.HOME" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>

通过将android.intent.category.HOME与android.intent.category.DEFAULT两个类添加至intent-filter组当中,相关Activity得以拥有与启动器概念相符的运行方式。当大家按下设备上的home按钮时,其还将作为选项方案显示出来。

我们还需要将launchMode设置到singleTask当中,从而确保无论何时都只有单一Activity实例由系统负责运行。要显示用户的墙纸图案,大家必须将主题设置为Theme.Wallpaper.NoTitleBar.FullScreen。

我们需要添加的第二个Activity负责显示已经安装在用户设备中的应用程序条目。它还有另一项任务,即启动这些应用程序。我们不需要对该Activity进行任何特殊配置,将其命名为AppsListActivity即可。
<activity android:name="ah.hathi.simplelauncher.AppsListActivity" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" > </activity>

4.Activity布局

下面在项目的res/layout文件夹中为HomeActivity类创建一个XML文件,并将其命名为activity_home.xml。该布局拥有一个单独的Button用以响应点触事件。点触该按钮能够让用户由主屏幕切换至应用程序列表。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".HomeActivity" > <Button android:id="@+id/apps_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:layout_marginRight="10dp" android:layout_marginTop="10dp" android:text="Show Apps" android:onClick="showApps" /> </RelativeLayout>

接下来,在项目的res/layout文件夹中为AppsListActivity类创建一个XML文件并将其命名为activity_apps_list.xml。该布局当中包含一个占据整个屏幕的ListView。
<?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" > <ListView android:id="@+id/apps_list" android:layout_width="match_parent" android:layout_height="match_parent" > </ListView> </LinearLayout>

最后,在同样的位置创建第三个XML文件并将其命名为list_item.xml。该文件用于定义ListView当中各个条目的布局方案。列表视图中的每个条目都代表着已经安装在用户设备上的一款应用程序。它能够显示该应用程序的图标、标签以及软件包名称。我们可以利用ImageView实例来显示该应用的图标,并通过TextView实例显示标签与软件包名称。
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="10dp" > <ImageView android:id="@+id/item_app_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerVertical="true" /> <TextView android:id="@+id/item_app_label" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@+id/item_app_icon" android:paddingLeft="10dp" /> <TextView android:id="@+id/item_app_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/item_app_label" android:layout_toRightOf="@+id/item_app_icon" android:paddingLeft="10dp" /> </RelativeLayout>

5.创建Acitivity类

HomeActivity

应用程序的布局方案创建完成之后,现在要做的是创建两个Activity类。当创建这两个类时,请确保每个类的名称都与我们之前在项目清单文件中所指定的内容相匹配。

创建一个名为HomeActivity的新类,然后将android.app.Activity设置为其超类。
package ah.hathi.simplelauncher; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; public class HomeActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_home); } public void showApps(View v){ Intent i = new Intent(this, AppsListActivity.class); startActivity(i); } }

在该类的onCreate方法中,我们调用setContentView并将其传递至之前已经创建完成的布局当中。大家可能还记得,我们曾为activity_home布局添加过一个按钮,用于触发名为showApps的方法。现在我们要做的是将该方法引入HomeActivity类当中。整个添加过程非常简单,各位需要做的只是为AppsListActivity类创建一个Intent并付诸运行。

H. android自定义控件怎么用

开发自定义控件的步骤:
1、了解View的工作原理
2、 编写继承自View的子类
3、 为自定义View类增加属性
4、 绘制控件
5、 响应用户消息
6 、自定义回调函数

一、View结构原理
Android系统的视图结构的设计也采用了组合模式,即View作为所有图形的基类,Viewgroup对View继承扩展为视图容器类。
View定义了绘图的基本操作
基本操作由三个函数完成:measure()、layout()、draw(),其内部又分别包含了onMeasure()、onLayout()、onDraw()三个子方法。具体操作如下:
1、measure操作
measure操作主要用于计算视图的大小,即视图的宽度和长度。在view中定义为final类型,要求子类不能修改。measure()函数中又会调用下面的函数:
(1)onMeasure(),视图大小的将在这里最终确定,也就是说measure只是对onMeasure的一个包装,子类可以覆写onMeasure()方法实现自己的计算视图大小的方式,并通过setMeasuredDimension(width, height)保存计算结果。

2、layout操作
layout操作用于设置视图在屏幕中显示的位置。在view中定义为final类型,要求子类不能修改。layout()函数中有两个基本操作:
(1)setFrame(l,t,r,b),l,t,r,b即子视图在父视图中的具体位置,该函数用于将这些参数保存起来;
(2)onLayout(),在View中这个函数什么都不会做,提供该函数主要是为viewGroup类型布局子视图用的;

3、draw操作
draw操作利用前两部得到的参数,将视图显示在屏幕上,到这里也就完成了整个的视图绘制工作。子类也不应该修改该方法,因为其内部定义了绘图的基本操作:
(1)绘制背景;
(2)如果要视图显示渐变框,这里会做一些准备工作;
(3)绘制视图本身,即调用onDraw()函数。在view中onDraw()是个空函数,也就是说具体的视图都要覆写该函数来实现自己的显示(比如TextView在这里实现了绘制文字的过程)。而对于ViewGroup则不需要实现该函数,因为作为容器是“没有内容“的,其包含了多个子view,而子View已经实现了自己的绘制方法,因此只需要告诉子view绘制自己就可以了,也就是下面的dispatchDraw()方法;
(4)绘制子视图,即dispatchDraw()函数。在view中这是个空函数,具体的视图不需要实现该方法,它是专门为容器类准备的,也就是容器类必须实现该方法;
(5)如果需要(应用程序调用了setVerticalFadingEdge或者setHorizontalFadingEdge),开始绘制渐变框;
(6)绘制滚动条;
从上面可以看出自定义View需要最少覆写onMeasure()和onDraw()两个方法。

二、View类的构造方法
创建自定义控件的3种主要实现方式:
1)继承已有的控件来实现自定义控件: 主要是当要实现的控件和已有的控件在很多方面比较类似, 通过对已有控件的扩展来满足要求。
2)通过继承一个布局文件实现自定义控件,一般来说做组合控件时可以通过这个方式来实现。
注意此时不用onDraw方法,在构造广告中通过inflater加载自定义控件的布局文件,再addView(view),自定义控件的图形界面就加载进来了。
3)通过继承view类来实现自定义控件,使用GDI绘制出组件界面,一般无法通过上述两种方式来实现时用该方式。

三、自定义View增加属性的两种方法:
1)在View类中定义。通过构造函数中引入的AttributeSet 去查找XML布局的属性名称,然后找到它对应引用的资源ID去找值。
案例:实现一个带文字的图片(图片、文字是onDraw方法重绘实现)

public class MyView extends View {

private String mtext;
private int msrc;

public MyView(Context context) {
super(context);
}

public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
int resourceId = 0;
int textId = attrs.getAttributeResourceValue(null, "Text",0);
int srcId = attrs.getAttributeResourceValue(null, "Src", 0);
mtext = context.getResources().getText(textId).toString();
msrc = srcId;
}

@Override
protected void onDraw(Canvas canvas) {
Paint paint = new Paint();
paint.setColor(Color.RED);
InputStream is = getResources().openRawResource(msrc);
Bitmap mBitmap = BitmapFactory.decodeStream(is);
int bh = mBitmap.getHeight();
int bw = mBitmap.getWidth();
canvas.drawBitmap(mBitmap, 0,0, paint);
//canvas.drawCircle(40, 90, 15, paint);
canvas.drawText(mtext, bw/2, 30, paint);
}
}

布局文件:

<?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" >

<com.example.myimageview2.MyView
android:id="@+id/myView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
Text="@string/hello_world"
Src="@drawable/xh"/>

</LinearLayout>

属性Text, Src在自定义View类的构造方法中读取。

2)通过XML为View注册属性。与Android提供的标准属性写法一样。
案例: 实现一个带文字说明的ImageView (ImageView+TextView组合,文字说明,可在布局文件中设置位置)

public class MyImageView extends LinearLayout {

public MyImageView(Context context) {
super(context);
}

public MyImageView(Context context, AttributeSet attrs) {
super(context, attrs);
int resourceId = -1;
TypedArray typedArray = context.obtainStyledAttributes(attrs,
R.styleable.MyImageView);
ImageView iv = new ImageView(context);
TextView tv = new TextView(context);
int N = typedArray.getIndexCount();
for (int i = 0; i < N; i++) {
int attr = typedArray.getIndex(i);
switch (attr) {
case R.styleable.MyImageView_Oriental:
resourceId = typedArray.getInt(
R.styleable.MyImageView_Oriental, 0);
this.setOrientation(resourceId == 1 ? LinearLayout.HORIZONTAL
: LinearLayout.VERTICAL);
break;
case R.styleable.MyImageView_Text:
resourceId = typedArray.getResourceId(
R.styleable.MyImageView_Text, 0);
tv.setText(resourceId > 0 ? typedArray.getResources().getText(
resourceId) : typedArray
.getString(R.styleable.MyImageView_Text));
break;
case R.styleable.MyImageView_Src:
resourceId = typedArray.getResourceId(
R.styleable.MyImageView_Src, 0);
iv.setImageResource(resourceId > 0 ?resourceId:R.drawable.ic_launcher);
break;
}
}
addView(iv);
addView(tv);
typedArray.recycle();
}
}

attrs.xml进行属性声明, 文件放在values目录下

<?xml version="1.0" encoding="utf-8"?>
<resources>

<declare-styleable name="MyImageView">
<attr name="Text" format="reference|string"></attr>
<attr name="Oriental" >
<enum name="Horizontal" value="1"></enum>
<enum name="Vertical" value="0"></enum>
</attr>
<attr name="Src" format="reference|integer"></attr>
</declare-styleable>

</resources>

MainActivity的布局文件:先定义命名空间 xmlns:uview="http://schemas.android.com/apk/res/com.example.myimageview2" (com.example.myimageview2为你
在manifest中定义的包名)
然后可以像使用系统的属性一样使用:uview:Oriental="Vertical"

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:uview="http://schemas.android.com/apk/res/com.example.myimageview2"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />

<com.example.myimageview2.MyImageView
android:id="@+id/myImageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
uview:Text="这是一个图片说明"
uview:Src="@drawable/tw"
uview:Oriental="Vertical">
</com.example.myimageview2.MyImageView>

</LinearLayout>

四、控件绘制 onDraw()

五、
六:自定义View的方法
onFinishInflate() 回调方法,当应用从XML加载该组件并用它构建界面之后调用的方法
onMeasure() 检测View组件及其子组件的大小
onLayout() 当该组件需要分配其子组件的位置、大小时
onSizeChange() 当该组件的大小被改变时
onDraw() 当组件将要绘制它的内容时
onKeyDown 当按下某个键盘时
onKeyUp 当松开某个键盘时
onTrackballEvent 当发生轨迹球事件时
onTouchEvent 当发生触屏事件时
onWindowFocusChanged(boolean) 当该组件得到、失去焦点时
onAtrrachedToWindow() 当把该组件放入到某个窗口时
onDetachedFromWindow() 当把该组件从某个窗口上分离时触发的方法
onWindowVisibilityChanged(int): 当包含该组件的窗口的可见性发生改变时触发的方法

I. android里tools:contexts是什么意思要通俗易懂的解释

工具属性
tools:context
这个属性通常在一个布局XML文件的根元素中设置,记录了这个布局关联到哪一个activity(因为显然一个布局在设计时可以被多个布局使用)(例如它会用于布局编辑器中以推断默认的主题,由于主题定义在Manifest中,并与activity而不是布局相关联。你可以和在manifests中一样使用点前缀,来指定activity类,而不需要使用完整的程序包名作为前缀。
<android.support.v7.widget.GridLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity" ... >
使用:Studio 和 Eclipse的布局编辑器,Lint

阅读全文

与androidxmlnstools相关的资料

热点内容
python字符串转string 浏览:357
在电影院不要说话用英语怎么说 浏览:807
重生香江开银行建立财团的小说 浏览:128
已上传到服务器什么意思 浏览:449
R命令dim 浏览:653
苹果ipad编程软件 浏览:282
javaodbcaccess 浏览:769
云服务器怎么对接 浏览:417
股票分时图源码 浏览:912
如何查询红帽服务器的日志文件 浏览:200
bcb开发51单片机 浏览:763
程序员男士图片 浏览:708
如何把pdf文件拆分 浏览:749
法国LOVE爱恋完整版观看 浏览:388
python自动安装程序 浏览:253
为什么有压缩分卷才能继续解压 浏览:316
AnalDelinquent 浏览:889
同人绿帽改编 浏览:625
生病的男人也要去找电影 浏览:566
邵氏全部电影 浏览:281