指数 介绍背景,论述基础 android活动生命周期的大小 视图 在屏幕上显示视图 让我们的代码 登录活动 TextView 编辑视图属性 edittext imageview按钮 单击事件 复选框创建视图布局的公共属性loginactivity 线性布局,相对布局,框架布局 创建LoginActivity(续) 受欢迎的活动 选项菜单创建WelcomeActivity 报名活动 单选按钮/单选组开关创建注册活动 概要文件的活动 添加逻辑 User类userservice类loginactivity signupactivity欢迎活动配置文件activity 用户列表的活动 创建UserListActivity 已完成的项目存储库感兴趣的历史点 , 介绍 在本文中,您将了解UI组件的概述。Android提供了基本的布局和控件,你可以用来创建你的应用程序的用户界面。然而,如果你不满意他们或你想要更多的组件,你可以自己做。 背景 Android应用UI是一件你必须学习的有趣的事情。它与其他平台有一点不同,但它的设计很棒。要学习这一课,您需要了解Android应用程序的基础,比如项目结构和资源。你可以从Hello Android文章中学习。 这些交易 在学习这篇文章之前,我想确保每个人都在同一个页面上。我已经为您提供了用于管理我们的课程材料的基础项目,您可以从下面的链接下载。 下载ViewAndLayoutLessons_- _base .zip - 436.5 KB 要打开基础项目,您需要解压缩它并打开Android Studio,然后单击file菜单并选择open。 选择项目文件夹并单击OK按钮。 如果你打开了另一个项目,Android Studio会要求你选择你想要打开项目的窗口。 现在,基地项目开放了。 创建项目并运行它。 你会看到这个应用程序的主屏幕只有一个列表。列表中有两个示例项目,您可以单击该项目查看示例活动。在我们的课程中,你将学习创建更多的活动,并将其添加到这个列表中。 活动模板 在本文中,我们将使用空白活动模板创建一个新的活动。 空白活动模板将生成Java代码、布局文件,并将活动自动应用到清单。 为了方便访问活动,当您创建活动时,您需要将其添加到MainActivity中的列表中。 隐藏,复制Code

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);//set the activity_main.xml as screen content List<ActivityData> activityDataList = new ArrayList<ActivityData>();//List of the ActivityData instance, put you ActivityData here
activityDataList.add(new ActivityData(getString(R.string.title_activity_sample_inflate_view_from_xml),SampleInflateViewFromXmlActivity.class));//add the ActivityData to the List
activityDataList.add(new ActivityData(getString(R.string.title_activity_sample_create_view_in_java_code),SampleCreateViewInJavaCodeActivity.class)); ...
}

我们使用,add()语句将活动添加到ListView中。您需要创建一个ActivityData实例,其中包含活动的标题和it类。 这是ActivityData类的构造函数: 隐藏,复制Code

ActivityData(String title,Class activityClass);

现在,尝试创建一个名为“MyFirstActivity”的新活动,并将其添加到列表中。 这是我的主活动。java代码: 隐藏,复制Code

....

public class MainActivity extends Activity {

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);//set the activity_main.xml as screen content List<ActivityData> activityDataList = new ArrayList<ActivityData>();//List of the ActivityData instance, put you ActivityData here
activityDataList.add(new ActivityData(getString(R.string.title_activity_sample_inflate_view_from_xml),SampleInflateViewFromXmlActivity.class));//add the ActivityData to the List
activityDataList.add(new ActivityData(getString(R.string.title_activity_sample_create_view_in_java_code),SampleCreateViewInJavaCodeActivity.class));
activityDataList.add(new ActivityData("My Fist Activity",MyFirstActivity.class)); ....
} .... }

当您运行应用程序时,您将在列表中看到一个MyFirstActivity项。 的基础 Android应用UI系统由View和ViewGroup组成。View是显示在屏幕上并且用户可以与之交互的元素,而ViewGroup用于对视图进行分组和对齐。 上图显示了Android应用程序UI是一个视图树。只能在根目录下放置一个元素。因此,ViewGroup是您应该考虑的第一选择,因为它允许您在屏幕上放置许多元素。 的大小 Android建议开发者避免使用像素坐标来定位和调整视图的大小。Android提供了用于分组和安排的ViewGourp或布局,以及用于调整视图大小的特殊单元。 下面是用于调整视图大小和对齐的特殊单位和值: MATCH_PARENT:设置元素的大小(宽度或高度)以适应其父元素。FILL_PARENT:与MATCH_PARENT相同,但支持Android 2.2及以下版本。WRAP_CONTENT:设置元素的大小(宽度或高度)以适应其父元素。dp(dip)单元:根据屏幕的物理密度计算的抽象单元。可用于定义元素的大小或它的边距和填充。sp单元:与dp单元相似,但它也计算用户喜欢的字体大小,建议用于调整文本大小。 Android活动生命周期 当你打开应用程序,切换到另一个,然后关闭它时,你的应用程序发生了什么?应用程序的活动将在称为“活动生命周期”的状态之间转换。 Android为每个Activity的状态提供回调方法。这样你就可以管理活动在进入特定状态时是如何工作的。例如,当应用关闭时停止音乐,当用户切换时结束数据流,另一个应用程序。 上面的图片显示了Android的活动生命周期,状态转换和回调方法。 当活动接收到意图时,它将调用onCreate()方法,您可以在此状态下构造此活动的UI。 创建后,onStart()方法将被调用,在这种状态下,您可以添加一些代码,希望在UI可见之前进行操作。 现在,UI显示出来了。Android会调用onResume()方法,你可以在每次应用恢复时添加你想要操作的内容,比如刷新数据。 恢复后,应用程序已完全运行,您可以与应用程序的UI交互,直到它暂停。 当你切换到另一个应用程序或转到主屏幕时,Activity会pause, onPause()和onSaveInstanceState()方法会调用。您需要保存未保存的数据,停止动画或UI工作,并减少资源的使用。 注意:数据可能在此状态后丢失。你需要自己保存它。 当活动不再可见时,UI将隐藏并且Android将调用onStop()方法,您可以杀死不再使用的服务。 如果导航回活动,onRestart()方法将调用并允许您启动一个活动。 当另一个活动需要更多资源时,Android会杀死未使用的活动。杀死后,用户仍然可以导航到该活动,Android将调用onCreate()方法来重新创建it。您可以恢复在暂停状态下保存的数据。 当Activity结束或Android请求销毁Activity时,Android会调用onDestroy()方法来释放线程、数据等资源。 用你的眼睛看 我创建了一个应用程序,用来学习生命周期回调方法调用的顺序,你可以在这里下载。 下载LifeCycleTest.zip - 278.9 KB 只需要将应用程序部署到你的设备上,然后尝试切换到其他应用程序返回或做一些事情让Activity转换到另一种状态。您将看到在每个状态中从Toast消息(浮动气球内的文本)调用的回调方法。 视图 视图是显示在屏幕上的视觉元素,它可能与用户有一些交互。Android提供了许多可在应用程序中使用的预定义视图。 您可以用Java代码和XML创建视图。我建议您使用XML,因为讨论模型、视图和控件的MVC概念应该是分开的。 这是在XML代码中使用视图的例子: 隐藏,复制Code

<Viewandroid:layout_width="wrap_content"android:layout_height="wrap_content"/>

注意:创建视图时必须使用layout_width和layout_height属性。 如果您想在Java代码中调用此视图,则需要添加id属性来标识此视图。 注意:id属性的值必须以“@+id/”开头,后面跟着名字,或者你可以使用Android的预定义id,比如“@ Android:id/text1” 隐藏,复制Code

<Viewandroid:id="@+id/my_view"android:layout_width="wrap_content"android:layout_height="wrap_content"/>

现在,您可以使用父视图的方法findViewById()在Java代码中调用这个视图,视图的id作为参数。 隐藏,复制Code

public class MainActivity extends ActionBarActivity {

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View myView = findViewById(R.id.my_view);
}
}

如果希望用Java代码创建视图,可以通过实例化该视图类的对象来实现。 隐藏,复制Code

public class MainActivity extends Activity {

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View myView findViewById(R.id.my_view);
View newView = new View(this);
}
}

现在,视图已经创建,但它不会显示在屏幕上,直到您将其添加到现有布局或将其设置为内容视图。 在屏幕上显示视图 在res/layout文件夹中创建布局文件之后,您需要在活动中放入一些代码来调用您想要在屏幕上显示的视图。Activity类提供了一个setContentView()方法,你可以传递布局的id或者视图实例作为参数。 示例1 看一下基本项目,文件名是“activity_sample_inflate_view_from_xml”。然后我想把它显示在SampleInflateViewFromXmlActivity中。 activity_sample_inflate_view_from_xml.xml SampleInflateViewFromXmlActivity.java 我必须将setContentView()语句放入到活动中,并使用布局id作为参数。 隐藏,复制Code

package me.vable.android.viewandlayoutlessons;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle; public class SampleInflateViewFromXmlActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample_inflate_view_from_xml);
}
}

注意:R类在Java代码中用于访问资源的id, 现在,构建并运行应用程序。 示例2 我有SampleCreateViewInJavaCodeActivity,但我不再想使用XML布局文件,但我想用Java代码创建视图。 注意:为了显示在java代码中构造的视图,你也必须使用setConTentView()方法,但是使用视图实例作为参数而不是布局的id。 以下是我的代码: 隐藏,复制Code

package me.vable.android.uiexample;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.widget.Button; public class SampleActivity extends ActionBarActivity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button helloWorldButton = new Button(this);
helloWorldButton.setText("Hello World");
setContentView(helloWorldButton);
}
}

我创建了按钮并将其设置为display content。结果如下: 现在,您可以在屏幕上显示视图。 , 让我们的代码 在这节课中,我将给你一个项目,你需要完成它。 这个项目叫做“UserSystem”,它包含5个活动,分别是登录活动、欢迎活动、注册活动、配置文件活动和用户列表活动。让我们看看屏幕模型。 登录活动 创建名为“LoginActivity”的新活动。那么请考虑它的UI。 注意:不要忘记将此活动添加到主页的列表中。 你会发现这个活动有5种类型的视图有图像,文本输入,复选框,文本链接,按钮。现在,将它们链接到Android基本视图类型。 要显示图像,你应该使用ImageView。文本输入——Android提供了EditText,它允许你设置输入类型,你也可以使用作为密码字段。Android在一个视图中提供带有标签的复选框。文本链接-没有文本链接的Android,因为你可以添加事件点击到每个视图。所以你可以用TextView代替。按钮-你可以使用按钮或其他你想要的视图 注:当我描述每个视图时,你可以创建一个新的活动来尝试它自己例如TextViewExampleActivity来学习如何使用TextView工作。 TextView 你可能知道一个TextView作为标签或文本块在其他平台。TextView是用来在屏幕上显示文本的最简单的视图。 创建TextView,只需拖动TextView从调色板,并拖到预览屏幕。 注:Android Studio提供了多种TextView,有纯文本、大文本、中文本和小文本。你可以选择一个你喜欢的。 打开XML视图,你会看到这样的TextView元素: 隐藏,复制Code

<TextViewandroid:text="New Text"android:layout_width="wrap_content"android:layout_height="wrap_content"/>

这些是有趣的属性的TextView: 文本—您希望在此视图上显示的文本。文本大小-文本的大小。文本颜色-文本的颜色。文本的样式(普通/斜体/粗体)。fontFamily—用于呈现文本的字体系列,如serif, sans-serif等。 示例:我想创建一个TextView,显示一个大红色粗体衬线文本“Hello World!” 隐藏,复制Code

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World"
android:textSize="36dp"
android:textColor="#FF0000"
android:fontFamily="serif"

/>

编辑视图属性 在Android Studio中有很多设置视图属性的方法 1. 使用XML代码 在布局文件的视图元素中,你可以添加已知的属性,比如id。如果你不知道属性名,你可以按Ctrl +空格键(Windows/Linux),然后建议就会显示出来。 隐藏,复制Code

<TextView
android:id="@+id/textview_hello_world"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World"
android:textSize="36dp"
android:textColor="#FF0000"
android:fontFamily="serif"

/>

不喜欢XML吗?您还可以使用GUI属性面板来编辑视图属性。 2. 使用属性面板 转到设计视图并单击您想要的视图。在Android Studio屏幕的右边,你会看到属性面板,其中包含一个列表视图的属性。 如果没有找到属性面板,你可能会看到一个“组件树”菜单。单击它,将出现属性面板。 设置所需的属性。 3.双击视图 当您双击该视图时,该视图的公共属性将显示,您可以在这里进行编辑。 注意:在2。和3。你会发现有一个按钮[…在一些属性值的右边,该按钮用于浏览资源,如字符串、drawable等。 在Java代码中访问TextView 您可以从Java代码访问每个视图实例,最简单的方法是使用该视图的id来查找特定的视图。 EditText EditText也称为文本框、文本字段或文本区域,它允许用户使用键盘输入/编辑文本。您可以指定输入数据类型,如数字、电子邮件、密码等。 您可以通过从调色板中拖动EditText(纯文本)并拖放到预览屏幕中来将EditText添加到屏幕中。 你可能得到一个小的TextView后拖放在预览屏幕上,因为宽度被设置为WRAP_CONTENT,让我们试着改变它为MATCH_PARENT。 隐藏,复制Code

<EditTextandroid:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/editText"/>

当您运行应用程序并点击EditText时,将出现软键盘。 以下是EditText有趣的属性: text—EditText的值。password -如果你设置为true,当你在EditText中输入一些东西时,它将显示每个字符为“•”。文本颜色-文本的颜色。提示-当值为空时出现的文本,用来猜测用户应该输入什么。提示文本的颜色,它应该比文本颜色浅。默认情况下,EditTextView允许用户输入多行文本,如文本区域,如果你不想要多行,设置这个属性为真。maxLines——您可以使用此属性限制文本的行数。inputType—限制用户在此EditText中可以输入的字符类型。 如果你想限制EditText中的数据,你可以设置输入类型,Android提供了很多输入类型,比如number, textUri, textEmailAddress等等。如果软键盘支持输入类型,则输入类型将影响键盘样式。 注意:输入类型只过滤键盘输入。如果你在java代码中设置文本输入类型将不会工作。 示例:当我将输入类型设置为number时,软键盘样式将会改变。 隐藏,复制Code

<EditTextandroid:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/edittext_test"android:layout_alignParentLeft="true"android:layout_alignParentStart="true"android:inputType="number"/>

访问Java代码中的EditText 现在,我们将访问Java中的EditText。设置EditText的id,然后可以使用findViewById()方法获取它的实例。 隐藏,复制Code

....
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_text_example);
EditText testEditText = (EditText) findViewById(R.id.edittext_test);
}
....

可以使用setText()方法设置EditText的值。 隐藏,复制Code

testEditText.setText("value from Java code");

这些是您应该知道的EditText的方法 getText()——返回EditText的值。通常与toString()方法一起使用,以获取作为字符串的值。setText()——设置EditText的值。setOnKeyListener()—设置用于检测一些关键事件(如enter key)的关键监听器。 ImageView 当您想要显示图像时,您应该使用ImageView。您可以通过从调色板中拖动它并拖放到预览屏幕中来创建ImageView。 当你把ImageView放到屏幕上时,它什么也不会显示,直到你设置它的src属性。src属性值是drawable resource,您需要向drawable-xxxx文件夹添加一个图像。 每个可绘制文件夹用于为特定设备提供图像。如果你在drawable-xhdpi中有图像,并且在小屏幕或低分辨率的设备上运行该应用程序,Android会将图像缩放到适合该设备的大小。我将在另一篇文章中描述替代资源。 注意:可绘制资源可以是图像文件和XML文件。 注意:如果可能的话,为每个dpi创建图像,因为自动缩放可能会降低性能。 要将图像添加到项目中,可以直接将其放入drawable-xxxx文件夹中。我建议你在XHDPI或XXHDPI上设计屏幕,使用Nexus 4(XHDPI)或5(XXHDPI)作为预览屏幕设备。 您可以双击ImageView来设置src属性。点击按钮[..]浏览可提取的资源。 , 这些是ImageView有趣的属性 调整视图边界- ImageView将保持高宽比(与图像相同)当你设置这个属性为真。缩放类型-如何缩放图像内容,如果它不适合ImageView。 您可以使用setImageDrawable()、setImageResource()或setImageBitmap()方法在Java代码中设置图像。 按钮 按钮是用户可以按下或单击以执行操作的视图。 你可以通过TextView这样的文本属性设置按钮上的文本,你可以通过属性drawableLeft, drawableRight, drawableTop,和drawableBottom添加图像到按钮。 单击事件 点击是你能与UI交互的最重要的动作,你可以通过实现OnClickListener接口来检测每个Android视图上的点击事件。 我有一个id为button的按钮 隐藏,复制Code

<Buttonandroid:id="@+id/button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="New Button"/>

然后,实现一个OnClickListener并将其设置为Button实例。 隐藏,复制Code

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast; public class ButtonExampleActivity extends ActionBarActivity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_button_example);
Button button = (Button)findViewById(R.id.button);
button.setOnClickListener(onClickListener);
} View.OnClickListener onClickListener= new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(ButtonExampleActivity.this,"Button was clicked",Toast.LENGTH_SHORT).show();
}
};
}

当我点击(点击)这个按钮,吐司信息将会显示。 另外,您可以使用XML代码中的onClick 属性来检测单击事件,而无需实现OnClikListener。 注意:如果视图不是一个按钮,您需要将clickable 属性设置为true。 注意:onClick只调用Activity的方法,不要在Fragment中使用它。 隐藏,复制Code

<Button
android:drawableLeft="@drawable/ic_launcher"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="drawableLeft"
android:onClick="buttonClick"
/> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Clickable TextView"
android:clickable="true"
android:onClick="buttonClick"

/>

您需要在活动中创建buttonClick(视图)方法 隐藏,复制Code

public void buttonClick(View view)
{
Toast.makeText(ButtonExampleActivity.this,"Invoke buttonClick() method",Toast.LENGTH_SHORT).show();
}

熟悉的视图:ImageButton,每个视图都有onClikListener实现。 复选框 复选框是可被选中或未选中的双状态按钮。在我们的项目中,我们将使用复选框作为一个Remember Me选项,用户可以选择该选项来保持登录状态。 隐藏,复制Code

<CheckBoxandroid:id="@+id/checkbox_remember_me"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="remember me"/>

您可以使用checked属性将其作为默认值进行检查。 隐藏,复制Code

<CheckBoxandroid:id="@+id/checkbox_remember_me"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="remember me"android:checked="true"/>

现在,尝试在Java代码中使用复选框。您可以使用isChecked()方法来获取检查状态。 隐藏,复制Code

CheckBox rememberMeCheckBox = (CheckBox) findViewById(R.id.checkbox_remember_me);

boolean rememberMe = rememberMeCheckBox.isChecked();

如果希望检测选中的更改,可以实现CompoundButton。OnCheckedChangeListener接口。 隐藏,复制Code

CompoundButton.OnCheckedChangeListener onRememberMeCheckBoxCheckedChange = new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
if(checked)
{
Toast.makeText(CheckBoxExampleActivity.this, "rememberMeCheckBox was checked", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(CheckBoxExampleActivity.this, "rememberMeCheckBox was unchecked", Toast.LENGTH_SHORT).show();
}
}
};

并将其设置为复选框。 隐藏,复制Code

rememberMeCheckBox.setOnCheckedChangeListener(onRememberMeCheckBoxCheckedChange);

熟悉的视图:开关,切换按钮。 , 创建LoginActivity 现在,你已经学会了5种基本观点。这就足够创建我们项目的活动了,请尝试现在创建它!!(只有UI部分) 注:请将每个视图的名称与下图相同。 结果漂亮吗?:( 现在,您将了解更多关于视图属性和用于构建更漂亮UI的布局的信息。 , 视图的公共属性 当每个视图从相同的基类扩展时,它们将拥有共同的属性/属性。我只描述重要的性质。 使视图透明、半透明或不透明。可能的值在0.0和1.0之间。背景——设置视图的背景。可单击—定义此视图对单击事件作出反应。视图的描述。重力——设置视图的内容位置。可能的值是left、top、right、bottom、center、center_horizontal、center_vertical或combine中的值其中的一些。id -视图的id。minHeight -视图的最小高度。minWidth -视图的最小宽度。onClick—用于对Clik事件作出反应的方法的名称。填充-设置所有四条边的填充。设置底部边缘的填充。设置结束边的填充。设置左边缘的填充。设置右边的填充。设置起始边的填充。设置顶部边缘的填充。saveEnabled -设置如果你想保存状态时UI冻结。标记——设置此视图的标记。可见性——设置视图可见性。 当视图被放置在布局下时,它们会收到一些属性,用于实现布局行为,如layout_margin, layout_gravity。 当你把宽度/高度设置为WRAP_CONTENT时,Android会把视图的宽度/高度设置得尽可能小。但如果你添加minWidth/minHeight到视图,Android会比较width/height和minWidth/minHeight,然后选择最大的一个。 当填充是内容和视图边界之间的间隙时,空白是相反的,它是这个视图和其他视图之间的间隙。 重力属性定义了在视图中放置内容的位置,而layout_gravity定义了在父视图(布局)中放置视图的位置。 布局 布局是什么?布局是一种ViewGroup,用于定义应用程序的UI结构,Android提供了多种布局,如线性布局,框架布局等。在本节中,您将了解每个布局的行为以及如何使用它们。 线性布局 线性布局是最简单的布局,它将它的子元素排列在单个列或行中。 它很容易使用,但功能强大。 使用LinearLayout,你可以衡量视图的宽度或高度。 例如:你在LinearLayout中有一个ImageView和内容,你想将图像缩放到LinearLayout高度的40%,并使用所有剩余的区域来显示内容。 这是当前的XML代码: 隐藏,收缩,复制Code

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical">

    <ImageViewandroid:id="@+id/image_view_logo"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="#FF99FF"/>

    <LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"android:background="#999999">
</LinearLayout>
</LinearLayout>

这就是你想要的: 您需要为LinearLayout设置weightSum属性。 我将LinearLayout的权重和设置为10。 注意:weightSum值可以是整数或小数 隐藏,复制Code

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:weightSum="10">
....

然后40%的10是4,你需要设置ImageView的权重为4。 隐藏,复制Code

<ImageViewandroid:id="@+id/image_view_logo"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="#FF99FF"android:layout_weight="4"/>

剩下的高度是60%,你必须设置内容的重量(内部线性布局)为6。 隐藏,复制Code

<LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"android:background="#999999"android:layout_weight="6">
</LinearLayout>

现在,你得到了你想要的UI。 注意:为了在使用权重行为时获得更好的性能,如果使用垂直线性布局,请将布局子元素的高度设置为0dp;如果使用水平线性布局,请将布局子元素的宽度设置为0dp。 隐藏,收缩,复制Code

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:weightSum="10">

    <ImageViewandroid:id="@+id/image_view_logo"android:layout_width="match_parent"android:layout_height="0dp"android:background="#FF99FF"android:layout_weight="4"/>

    <LinearLayoutandroid:layout_width="match_parent"android:layout_height="0dp"android:orientation="vertical"android:background="#999999"android:layout_weight="6">
</LinearLayout> </LinearLayout>

相对布局 RelativeLayout是一个非常灵活的布局,它将它的子节点安排到相对位置。每个子元素可以是相对于兄弟元素的特定位置,比如在另一个视图的上面,在另一个视图的左边。RelativeLayout允许视图重叠或浮动视图,它比嵌套LinearLayout有更好的性能。 在许多应用程序中都可以看到相对布局,比如Facebook和谷歌+。 这些是RelativeLayout子视图的有趣属性 layout_alignParentTop—将视图放在RelativeLayout的顶部。layout_alignParentBottom—将视图放置在RelativeLayout的底部。layout_alignParentLeft—将视图放在RelativeLayout的左侧。layout_alignParentRight—将视图放置在RelativeLayout的右侧。layout_centerInParent 把视图放在相对距离的中心。layout_centerHorizontal—将视图置于相对布局的水平中心位置。layout_centerVertical—将视图置于相对布局的垂直中心位置。layout_toLeftOf—将该视图放置到其他视图的左侧。layout_toRightOf—将视图放置到其他视图的右侧。layout_above—将视图放在其他视图的上面。layout_below—将视图放到其他视图的下面。 似乎很难吗?您可以在design视图的RelativeLayout上拖放视图来定位它们。 注意:您需要为每个RelativeLayout的子视图设置id属性,以便在相对位置引用。 示例:你想创建一个论坛应用程序,在线程列表页面上,你想创建这样的列表项: 你决定使用相对线程项目UI,让我们现在尝试一下!! 下图展示了各视图之间的关系 以下是我的代码: 隐藏,收缩,复制Code

<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="70dp"android:background="#252525"android:padding="8dp"android:layout_margin="8dp">

    <ImageViewandroid:id="@+id/imageview_icon"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_alignParentLeft="true"android:layout_alignParentTop="true"android:src="@drawable/ic_launcher"/>

    <TextViewandroid:id="@+id/textview_title"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_above="@+id/textview_content"android:layout_alignParentRight="true"android:layout_alignParentTop="true"android:layout_toRightOf="@+id/imageview_icon"android:text="Title"android:textColor="@android:color/white"android:textSize="24sp"/>

    <TextViewandroid:id="@+id/textview_content"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_alignParentRight="true"android:layout_toRightOf="@+id/imageview_icon"android:text="Content"android:textColor="@android:color/secondary_text_dark"android:textSize="18sp"/>
</RelativeLayout>

这就是结果!! 框架布局 FrameLayout设计为只显示一个子元素,将其放置在布局中心的边框上。但是,您可以向FrameLayout添加多个子视图,但是视图可能会与其他视图重叠,因此您无法控制它。 当视图在FrameLayout可以重叠,你可以创建覆盖元素像谷歌+的写按钮。 注意:要在FrameLayout中定位视图,您可以在子视图上使用layout_gravity和layout_margin属性。 FramLayout示例代码: 隐藏,收缩,复制Code

<FrameLayoutxmlns: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="me.vable.android.viewandlayoutlessons.FrameLayoutExampleActivity">

    <TextViewandroid:text="top|left"android:textSize="20sp"android:gravity="center"android:layout_width="100dp"android:layout_height="100dp"android:background="#FF99FF"android:layout_gravity="top"/>

    <TextViewandroid:text="right|bottom"android:textSize="20sp"android:gravity="center"android:layout_width="100dp"android:layout_height="100dp"android:background="#FF99FF"android:layout_gravity="right|bottom"/>

    <TextViewandroid:text="bottom|center"android:textSize="20sp"android:gravity="center"android:layout_width="100dp"android:layout_height="100dp"android:background="#FF99FF"android:layout_gravity="center_horizontal|bottom"/>

    <TextViewandroid:text="left|bottom"android:textSize="20sp"android:gravity="center"android:layout_width="100dp"android:layout_height="100dp"android:background="#FF99FF"android:layout_gravity="left|bottom"/>

    <TextViewandroid:text="right|center"android:textSize="20sp"android:gravity="center"android:layout_width="100dp"android:layout_height="100dp"android:background="#FF99FF"android:layout_gravity="right|center_vertical"/>

    <TextViewandroid:text="center"android:textSize="20sp"android:gravity="center"android:layout_width="100dp"android:layout_height="100dp"android:background="#FF99FF"android:layout_gravity="center"/>

    <TextViewandroid:text="left|center"android:textSize="20sp"android:gravity="center"android:layout_width="100dp"android:layout_height="100dp"android:background="#FF99FF"android:layout_gravity="left|center_vertical"/>

    <TextViewandroid:text="top|right"android:textSize="20sp"android:gravity="center"android:layout_width="100dp"android:layout_height="100dp"android:background="#FF99FF"android:layout_gravity="right|top"/>

    <TextViewandroid:text="top|center"android:textSize="20sp"android:gravity="center"android:layout_width="100dp"android:layout_height="100dp"android:background="#FF99FF"android:layout_gravity="center_horizontal|top"/>
<ImageView       android:layout_width="50dp"       android:layout_height="50dp"       android:id="@+id/imageView"       android:layout_gravity="right|bottom"       android:src="@drawable/ic_error"       android:layout_margin="80dp"/> </FrameLayout>

, 创建LoginActivity(续) 现在,我认为您可以通过使用所学的一切来为LoginActivity创建更好的UI,让我们开始吧!! 我将在下面展示我的布局(自己试试,不要复制) 隐藏,收缩,复制Code

<RelativeLayoutxmlns: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="me.vable.android.viewandlayoutlessons.LoginActivity">

    <ImageViewandroid:layout_width="match_parent"android:layout_height="200dp"android:id="@+id/imageview_app_logo"android:layout_alignParentTop="true"android:layout_centerHorizontal="true"android:src="@drawable/ic_launcher"android:adjustViewBounds="true"android:padding="32dp"android:background="#2DABFF"android:layout_marginBottom="16dp"/>

    <EditTextandroid:id="@+id/edittext_username"android:layout_centerHorizontal="true"android:hint="Username"android:layout_width="250dp"android:layout_height="wrap_content"android:layout_below="@+id/imageview_app_logo"android:singleLine="true"android:maxLines="1"/>

    <EditTextandroid:id="@+id/edittext_password"android:layout_below="@+id/edittext_username"android:layout_alignRight="@+id/edittext_username"android:layout_alignLeft="@+id/edittext_username"android:hint="Password"android:layout_width="0dp"android:layout_height="wrap_content"android:inputType="textPassword"android:ems="10"android:singleLine="true"android:maxLines="1"/>

    <CheckBoxandroid:id="@+id/checkbox_remember_me"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="remember me"android:layout_below="@+id/edittext_password"android:layout_alignLeft="@+id/edittext_password"android:layout_marginLeft="8dp"android:layout_marginTop="16dp"/>

    <TextViewandroid:id="@+id/textview_forgot_password"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textAppearance="?android:attr/textAppearanceSmall"android:text="forgot password?"android:layout_below="@+id/checkbox_remember_me"android:layout_centerHorizontal="true"android:layout_marginTop="16dp"android:textColor="#FF4040"/>

    <LinearLayoutandroid:orientation="horizontal"android:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_alignParentLeft="true"android:layout_alignParentStart="true"android:weightSum="2">

        <Buttonandroid:id="@+id/button_sign_up"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Sign up"android:layout_weight="1"/>

        <Buttonandroid:id="@+id/button_login"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Login"android:layout_weight="1"/>

    </LinearLayout>
</RelativeLayout>

, 受欢迎的活动 用户登录后会看到欢迎页面,该页面只显示个人资料图片和问候文字。只有一个选项菜单你还没学过,我们将在这个部分中了解它。 选项菜单 Android提供了一个标准的菜单组件。为了保持一致性,您应该使用标准菜单,而不是构建自己的菜单。在传统的Android版本中,有一个菜单硬件按钮用来打开选项菜单,但是在Android 3.0和上面的选项菜单是操作栏的一部分。谷歌提供了AppCompat库,用于创建遗留Android版本的操作栏,为所有设备带来相同的体验。 在Android 3.0+上,选项菜单分为两种类型,分别是动作菜单(在动作栏上以图标的形式显示)和弹出菜单(子菜单,直到你点击菜单才会崩溃的菜单)。 要创建options菜单,您需要在res/menu中创建一个菜单资源(当您使用空白活动模板时,该菜单资源将自动生成)。 现在,我已经用菜单资源名options_menu_example.xml创建了OptionsMenuExampleActivity。 这是一个XML代码 隐藏,复制Code

<menuxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"tools:context="me.vable.android.viewandlayoutlessons.OptionsMenuExampleActivity">
<itemandroid:id="@+id/action_settings"android:title="@string/action_settings"android:orderInCategory="100"app:showAsAction="never"/>
</menu>

默认情况下,空白活动模板将生成带有设置菜单的菜单资源。 这些是选项菜单的重要属性 id -这个菜单的id,没有id你就可以在Java代码中访问菜单。标题-你想要在这个菜单上显示的文本。orderInCategory——该菜单在其类别中的顺序。图标——此菜单的图标,当菜单为动作菜单时显示,并且总是显示在旧风格的菜单(遗留的android)上。app:showAsAction / android:showAsAction  -这个菜单是动作菜单吗,你可以设置它总是显示为动作菜单,或取决于动作栏的空间,或永远不显示为动作菜单。 注意:如果你的Activity是从AppCompat库的ActionBarActivitiy扩展的,你需要导入一个app名称空间xmlns:app="http://schemas.android.com/apk/res-auto"并使用app名称空间中的showAsAction。或者你可以同时添加app: showasaction&android:showAsAction来确保动作菜单会显示出来。 我建议您将菜单的id命名为action_<name>如果是动作菜单或menu_<name>如果是正常的菜单。 我将创建一个关于菜单作为一个弹出菜单。 隐藏,复制Code

<itemandroid:id="@+id/menu_about"android:title="About"android:orderInCategory="101"app:showAsAction="never"/>

我想显示关于菜单下的设置菜单,然后我设置它的顺序为101(大它低)。 接下来,我将创建refresh菜单作为操作菜单。 隐藏,复制Code

<itemandroid:id="@+id/action_refresh"android:title="Refresh"android:orderInCategory="1"app:showAsAction="always"/>

结果如下: 当你创建一个动作菜单时,你应该添加菜单图标。Android建议使用单色图像作为菜单图标,你必须创建的图像,简单,有明确的含义和众所周知的。 我决定使用这个图标来刷新菜单。Android Studio提供了图像资产导入向导,帮助开发者将图像转换为合适的大小和颜色。要使用向导,右键单击res文件夹,然后选择New >图像的资产。 您将看到向导窗口 有3种可绘制的资产类型,你可以使用这个向导来导入,有启动图标,操作栏和选项卡图标,以及通知图标。 我们将使用操作栏和标签图标选项来导入菜单图标。 这些是选项的描述。 资产类型-你想要创建前景的资产类型-你可以使用自己的图像,或使用剪贴画,或文本。 图像文件-如果你使用你自己的图像,向导会让你选择图像。剪纸艺术-如果你设置前景为剪纸艺术,向导将让你选择剪纸艺术。文本-如果你设置前台为文本,你可以在这里输入你的文本。字体-设置文本的字体。 修剪周围的空白空间-修剪前景元素周围的空间。附加填充—在前景元素周围添加空间。主题-你的应用的主题,如果你选择一个自定义选项,它会让你选择图标的颜色。资源名称——设置此资产的名称。 注意:资源名应该是ic_action_<name> 选择选项后,单击next按钮,您将看到输出预览。 我看不到我的图像,因为它的颜色是白色的:(选择目标模块,你的应用,sel检查你的应用程序的res目录。 现在,我有一个可绘制的资源名称ic_action_refresh。把它添加到菜单中!! 隐藏,复制Code

<itemandroid:id="@+id/action_refresh"android:title="Refresh"android:orderInCategory="1"app:showAsAction="always"android:icon="@drawable/ic_action_refresh"/>

结果如下: 接下来,我们将用Java代码访问options菜单,并编写代码以响应选项菜单单击事件。 打开活动文件,您将看到onCreateOptionsMenu()和onOptionsItemSelected()方法(如果不存在就创建它) 隐藏,复制Code

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.options_menu_example, menu);
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}

onCreateOptionsMenu()方法用于膨胀选项菜单以在视图中显示。 onOptionsItemSelected()方法用于检测菜单上的单击事件。 现在,我们关注onOptionsItemSelected()方法,我将显示每个菜单的Toast消息。 隐藏,复制Code

@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
//do something
Toast.makeText(this,"Settings menu was clicked",Toast.LENGTH_SHORT).show();
return true;
}
else if (id == R.id.menu_about) {
//do something
Toast.makeText(this,"About menu was clicked",Toast.LENGTH_SHORT).show();
return true;
}
else if (id == R.id.action_refresh) {
//do something
Toast.makeText(this,"Refresh menu was clicked",Toast.LENGTH_SHORT).show();
return true;
}
return super.onOptionsItemSelected(item);
}

运行应用程序!! , , 创建WelcomeActivity 现在,您已经了解了用于创建我们项目的WelcomeActivity的所有内容。现在创建它,并设置视图的id和菜单的id,如下图所示。 以下是我的代码: welcome.xml(菜单): 隐藏,收缩,复制Code

<RelativeLayoutxmlns: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"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"android:paddingBottom="@dimen/activity_vertical_margin"tools:context="me.vable.android.viewandlayoutlessons.WelcomeActivity">

    <ImageViewandroid:layout_width="100dp"android:layout_height="100dp"android:adjustViewBounds="true"android:id="@+id/imageview_profile"android:layout_alignParentTop="true"android:layout_centerHorizontal="true"android:layout_marginTop="32dp"android:src="@drawable/ic_man"/>

    <TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:textAppearance="?android:attr/textAppearanceMedium"android:text="Hello, John"android:id="@+id/textview_greeting"android:layout_below="@+id/imageview_profile"android:layout_centerHorizontal="true"android:layout_marginTop="16dp"/>
</RelativeLayout>

activity_welcome.xml(布局): 隐藏,收缩,复制Code

<menuxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"tools:context="me.vable.android.viewandlayoutlessons.WelcomeActivity">
<itemandroid:id="@+id/menu_user_list"android:title="User List"android:orderInCategory="1"app:showAsAction="never"/>
<itemandroid:id="@+id/menu_profile"android:title="My Profile"android:orderInCategory="2"app:showAsAction="never"/>
<itemandroid:id="@+id/menu_logout"android:title="Log Out"android:orderInCategory="3"app:showAsAction="never"/>
</menu>

, 报名活动 当用户打开应用程序,他们会发现LoginActivity,如果他们没有帐户,他们需要注册一个新的。还有一个RadioButton, RadioGroup,和Switch我们还没学过。现在,我们将学习创建一个注册活动。 RadioButton / RadioGroup RadioButton和RadioGroup一起用于创建一系列项,但是一次只能选择一个项。 RadioGroup是用来控制RadioButton的视图组,它只允许用户选择一个项目。 注意:在像线性布局这样的放射组中有方向属性。 几乎RadioButton的属性就像复选框的特性。我想你可以自己试一试。 例子:我想创建一个单一的选择问题,像上面的图片。以下是我的代码: 隐藏,收缩,复制Code

<LinearLayoutxmlns: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"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"android:paddingBottom="@dimen/activity_vertical_margin"tools:context="me.vable.android.viewandlayoutlessons.RadioButtonExampleActivity"android:orientation="vertical">

    <TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:textAppearance="?android:attr/textAppearanceMedium"android:text="what are you feeling right now?"android:id="@+id/textView"/>

    <RadioGroupandroid:id="@+id/radiogroup_feeling"android:layout_width="fill_parent"android:layout_height="wrap_content">

        <RadioButtonandroid:id="@+id/radiobutton_felling_happy"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Happy"/>

        <RadioButtonandroid:id="@+id/radiobutton_felling_sad"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Sad"/>

        <RadioButtonandroid:id="@+id/radiobutton_felling_bored"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Bored"/>
</RadioGroup>
</LinearLayout>

现在,我想检测什么按钮被选中,实现OnCheckedChangeListener的RadioGroup来检测选择变化。您将看到onCheckedChanged()方法,它将在所选项目发生更改时调用,它提供RadioButton的RadioGroup和id作为参数。 隐藏,收缩,复制Code

package me.vable.android.viewandlayoutlessons;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.RadioGroup;
import android.widget.Toast; public class RadioButtonExampleActivity extends ActionBarActivity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_radio_button_example);
RadioGroup feelingRadioGroup = (RadioGroup) findViewById(R.id.radiogroup_feeling);
feelingRadioGroup.setOnCheckedChangeListener(onCheckedChangeListener); } RadioGroup.OnCheckedChangeListener onCheckedChangeListener= new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
if(i == R.id.radiobutton_felling_happy)
{
Toast.makeText(RadioButtonExampleActivity.this,"You're happy!!",Toast.LENGTH_SHORT).show();
}
else if(i == R.id.radiobutton_felling_sad)
{
Toast.makeText(RadioButtonExampleActivity.this,"You're sad",Toast.LENGTH_SHORT).show();
}
else if(i == R.id.radiobutton_felling_bored)
{
Toast.makeText(RadioButtonExampleActivity.this,"You're bored",Toast.LENGTH_SHORT).show();
}
}
};

}

, 开关 开关就像复选框一样工作,但它看起来像真实世界中的开关。你可以在上面设置开/关标签。需要切换Android 4.0或以上版本,如果您的设备运行的Android版本低于4.0,请使用复选框代替。 下面是一个例子: 隐藏,复制Code

<Switchandroid:id="@+id/switch_subscription"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Email subscriptions"android:textOn=""/>

您还可以通过使用textOn和textOff属性来设置on/off文本 隐藏,复制Code

<Switchandroid:id="@+id/switch_subscription"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Email subscriptions"android:textOn="Yes"android:textOff="No"/>

熟悉的视图:复选框,切换按钮。 , 创建SignUpActivity 现在就让我们创建注册活动吧!! 注意:请使用我在下面图片中提供的id。 以下是我的代码: activity_sign_up.xml 隐藏,收缩,复制Code

<RelativeLayoutxmlns: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"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"android:paddingBottom="@dimen/activity_vertical_margin"tools:context="me.vable.android.viewandlayoutlessons.SignupActivity">

    <ImageViewandroid:layout_width="100dp"       android:layout_height="100dp"       android:adjustViewBounds="true"android:id="@+id/imageview_profile"android:layout_alignParentTop="true"android:layout_centerHorizontal="true"android:layout_marginTop="32dp"android:src="@drawable/ic_man"/>

    <EditTextandroid:id="@+id/edittext_username"android:layout_width="250dp"android:layout_height="wrap_content"android:textAppearance="?android:attr/textAppearanceMedium"android:hint="Username"android:layout_below="@+id/imageview_profile"android:layout_centerHorizontal="true"android:layout_marginTop="16dp"/>

    <EditTextandroid:id="@+id/edittext_password"android:layout_width="250dp"android:layout_height="wrap_content"android:textAppearance="?android:attr/textAppearanceMedium"android:hint="Password"android:password="true"android:layout_below="@+id/edittext_username"android:layout_centerHorizontal="true"/>

    <EditTextandroid:id="@+id/edittext_email"android:inputType="textEmailAddress"android:layout_width="250dp"android:layout_height="wrap_content"android:textAppearance="?android:attr/textAppearanceMedium"android:hint="Username"android:layout_below="@+id/edittext_password"android:layout_centerHorizontal="true"/>
<RadioGroupandroid:id="@+id/radiogroup_gender"android:layout_width="250dp"android:layout_height="wrap_content"android:orientation="horizontal"android:layout_below="@+id/edittext_email"android:layout_centerHorizontal="true">
<RadioButtonandroid:id="@+id/radiobutton_male"android:text="male"android:layout_width="wrap_content"android:layout_height="wrap_content"/>
<RadioButtonandroid:text="female"android:id="@+id/radiobutton_female"android:layout_width="wrap_content"android:layout_height="wrap_content"/>
</RadioGroup> <Switchandroid:id="@+id/switch_subscription"android:layout_width="300dp"android:layout_height="wrap_content"android:text="Email subscriptions"android:layout_centerHorizontal="true"android:layout_marginTop="16dp"android:layout_below="@+id/radiogroup_gender"/> <Switchandroid:id="@+id/switch_allow_email"android:layout_width="300dp"android:layout_height="wrap_content"android:text="Allow email from other"android:layout_centerHorizontal="true"android:layout_marginTop="16dp"android:layout_below="@+id/switch_subscription"/> </RelativeLayout>

sign_up.xml(选项菜单) 隐藏,复制Code

<menuxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"tools:context="me.vable.android.viewandlayoutlessons.SignUpActivity">
<itemandroid:id="@+id/action_submit"android:icon="@drawable/ic_action_check"android:title="Submit"app:showAsAction="always"/>
</menu>

然后,在设备上运行应用程序!! , 概要文件的活动 ProfileActivity将显示不带密码的用户信息。请自己创建它!! 完成后,在创建下一个活动之前,我们将向每个活动添加逻辑。 添加逻辑 在创建最后一个活动之前,我们将为每个活动添加逻辑代码,以使我们的应用程序工作。我已经在基础项目中提供了逻辑代码,你只需要实现它将你的活动。 用户类 User是用于存储用户信息的类。 以下是User类的属性: ,,私人字符串的用户名;,,私人密码字符串;,,私人字符串邮件;,,私人字符串profileImage;,,私人性别性别;,,私人布尔newsletterSubscribed;,,私人布尔allowedOtherEmail; Use可以通过访问器方法(get/set)设置或获取它。 这是性别枚举的结构 隐藏,复制Code

public enum Gender implements Serializable {
MALE,FEMALE
}

UserService类 UserService用于管理用户帐户,有创建新用户、登录、注销等功能,您将使用这个类与屏幕交互。 这些是这个类的方法: getInstance()—获取该类的当前实例。getCurrentUser() -获取当前登录用户。login()——使用用户名和密码对用户进行身份验证,您需要传递LoginListener以用于接收结果。登出()-从系统登出。register()—创建一个新的用户帐户,您需要传递RegisterListenerfor用于接收结果。getProfileImage() -返回用户配置文件图像的位图对象。getUserList()—获取用户帐户的列表,您需要传递用于接收结果的GetUserListListener。 这是你需要的界面t当使用某些方法时实现。 隐藏,复制Code

public interface LoginListener
{
public void onResponce(boolean loggedin,String message, User user);
} public interface RegisterListener
{
public void onResponce(boolean registered, String message, User user);
} public interface GetUserListListener
{
public void onResponce(boolean success, String message, List<User> users);
}

每个接口将在第一个参数中返回结果,在第二个参数中返回消息,第三个参数是用户对象或用户列表对象。 LoginActivity 现在,开始使用LoginActivity。 首先,你需要获得视图的所有实例。 隐藏,复制Code

private EditText usernameEditText;
private EditText passwordEduitText;
private CheckBox rememberMeCheckBox;
private TextView forgotPasswordTextView;
private Button loginButton;
private Button signUpButton; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login); usernameEditText = (EditText) findViewById(R.id.edittext_username);
passwordEduitText = (EditText) findViewById(R.id.edittext_password);
rememberMeCheckBox = (CheckBox) findViewById(R.id.checkbox_remember_me);
forgotPasswordTextView = (TextView) findViewById(R.id.textview_forgot_password);
loginButton = (Button) findViewById(R.id.button_login);
signUpButton = (Button) findViewById(R.id.button_sign_up);
}

接下来,我们将创建login()方法。 隐藏,复制Code

private void login(String username,String password)
{
progressDialog.show();
UserService.getInstance(LoginActivity.this).login(username, password, loginListener);
}

login()方法将调用UserService类的登录方法。 注意:您需要使用UserService. getinstance(上下文)来获得UserService类上的实例,不要自己创建它。 创建ProgressDialog,在执行长操作方法()时显示 隐藏,复制Code

private ProgressDialog progressDialog;

    @Override
protected void onCreate(Bundle savedInstanceState) {
...
progressDialog = new ProgressDialog(LoginActivity.this);
progressDialog.setIndeterminate(true);
...
}

然后我们需要实现LoginListener来接收结果回调。 隐藏,收缩,复制Code

UserService.LoginListener loginListener = new UserService.LoginListener() {
@Override
public void onResponce(boolean loggedin, String message, User user) {
progressDialog.dismiss();
Toast.makeText(LoginActivity.this,message,Toast.LENGTH_SHORT).show();
if(loggedin)
{
SharedPreferences sharedPreferences = getSharedPreferences("user_data",MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
if(rememberMeCheckBox.isChecked())
{
editor.putBoolean("remembered", true);
editor.putString("username", user.getUsername());
editor.putString("password", user.getPassword());
}
else
{
editor.putBoolean("remembered",false);
editor.remove("username");
editor.remove("password");
}
editor.commit();
goToWelcomeActivity();
}
}
};

如果登录成功,我们需要检查“记住我”按钮状态。如果用户想要记住,我们需要将帐户数据保存到SharePreferences中。 Android提供了SharedPreferences来存储应用程序数据,比如设置。您可以从上下文类的getSharedPreferences()方法获得SharePreferences实例。您可以使用SharedPreferences保存或管理数据。编辑器类。 注意:每次使用添加、删除或编辑SharedPreferences数据时,您都需要使用edit .commit()方法提交数据。 当用户登录时,您需要使用WelcomeActivity。因此,我创建了goToWelcomeActivity()方法来完成这项工作。 隐藏,复制Code

private void goToWelcomeActivity()
{
Intent intent = new Intent(this,WelcomeActivity.class);
startActivity(intent);
finish();
}

intent对象就像你发送给安卓的消息,安卓收到意图后会找到那个意图的责任人。当你切换到另一个Activity时,你需要创建一个Intent并传递上下文和另一个Activity类,然后调用startActivity()方法。finish()方法用于结束活动,用户登录后我们将完成活动,因为我们不再需要它了。 接下来,我们将检测Login按钮的单击事件。 隐藏,复制Code

@Override
protected void onCreate(Bundle savedInstanceState) {
...
loginButton.setOnClickListener(onClickLoginButtonListener);
...
} View.OnClickListener onClickLoginButtonListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
String username = usernameEditText.getText().toString();
String password = passwordEduitText.getText().toString();
login(username, password);
}
};

我们需要获取usernameEditText和passwordEditText的值,并将它们传递到login()方法中。 在此之后,我们必须实现注册按钮的单击事件。 隐藏,复制Code

@Override
protected void onCreate(Bundle savedInstanceState) {
...
signUpButton.setOnClickListener(onClickSignUpButtonListener);
...
} View.OnClickListener onClickSignUpButtonListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
goToSignupActivity();
}
}; private void goToSignupActivity()
{
Intent intent = new Intent(this,SignUpActivity.class);
startActivity(intent);
}

当用户点击注册按钮时,应用程序将导航到注册活动。 几乎完成,现在有忘记密码TextView,将用于更新密码,但我们现在没有那个功能。我们需要告诉用户这个函数没有实现。 隐藏,复制Code

@Override
protected void onCreate(Bundle savedInstanceState) {
...
forgotPasswordTextView.setOnClickListener(onClickForgotPasswordTextViewListener);
}
...
View.OnClickListener onClickForgotPasswordTextViewListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(LoginActivity.this);
builder.setTitle("Waraing");
builder.setIcon(R.drawable.ic_error);
builder.setMessage("Not implement");
builder.setPositiveButton("OK",null);
builder.show();
}
};

我创建了AlertDialog来向用户显示这个函数没有实现。 接下来,我们需要检查用户进入该活动时的登录状态,如果用户已经登录,应用程序应该立即导航到WelcomeActivity。 隐藏,复制Code

    @Override
protected void onCreate(Bundle savedInstanceState) {
...
if(UserService.getInstance(this).getCurrentUser()!=null)
        {
            goToWelcomeActivity();
            return;
        }
}

要检查statuc中的日志,您可以使用UserService的medthod getCurrentUser(),如果当前用户不是null,您需要切换到WelcomeActivity。 最后,如果我们已经从Remember Me函数存储了用户数据,则需要立即登录该用户。 隐藏,复制Code

    @Override
protected void onCreate(Bundle savedInstanceState) {
...
SharedPreferences sharedPreferences = getSharedPreferences("user_data",MODE_PRIVATE);
        boolean remembered = sharedPreferences.getBoolean("remembered",false);
        if(remembered)
        {
            rememberMeCheckBox.setChecked(true);
            String username = sharedPreferences.getString("username", null);
            String password = sharedPreferences.getString("password", null);
            login(username,password);
        }
}

这里是一个完整的源代码: 隐藏,收缩,复制Code

package me.vable.android.viewandlayoutlessons;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import me.vable.android.viewandlayoutlessons.data.User;
import me.vable.android.viewandlayoutlessons.data.service.UserService; public class LoginActivity extends ActionBarActivity { private EditText usernameEditText;
private EditText passwordEduitText;
private CheckBox rememberMeCheckBox;
private TextView forgotPasswordTextView;
private Button loginButton;
private Button signUpButton;
private ProgressDialog progressDialog; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login); if(UserService.getInstance(this).getCurrentUser()!=null)
{
goToWelcomeActivity();
return;
} progressDialog = new ProgressDialog(LoginActivity.this);
progressDialog.setIndeterminate(true); usernameEditText = (EditText) findViewById(R.id.edittext_username);
passwordEduitText = (EditText) findViewById(R.id.edittext_password);
rememberMeCheckBox = (CheckBox) findViewById(R.id.checkbox_remember_me);
forgotPasswordTextView = (TextView) findViewById(R.id.textview_forgot_password);
loginButton = (Button) findViewById(R.id.button_login);
signUpButton = (Button) findViewById(R.id.button_sign_up); loginButton.setOnClickListener(onClickLoginButtonListener);
signUpButton.setOnClickListener(onClickSignUpButtonListener);
forgotPasswordTextView.setOnClickListener(onClickForgotPasswordTextViewListener); SharedPreferences sharedPreferences = getSharedPreferences("user_data",MODE_PRIVATE);
boolean remembered = sharedPreferences.getBoolean("remembered",false);
if(remembered)
{
rememberMeCheckBox.setChecked(true);
String username = sharedPreferences.getString("username", null);
String password = sharedPreferences.getString("password", null);
login(username,password);
}
} private void login(String username,String password)
{
progressDialog.show();
UserService.getInstance(LoginActivity.this).login(username, password, loginListener);
} private void goToSignupActivity()
{
Intent intent = new Intent(this,SignUpActivity.class);
startActivity(intent);
} private void goToWelcomeActivity()
{
Intent intent = new Intent(this,WelcomeActivity.class);
startActivity(intent);
finish();
} View.OnClickListener onClickLoginButtonListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
String username = usernameEditText.getText().toString();
String password = passwordEduitText.getText().toString(); login(username, password);
}
}; View.OnClickListener onClickSignUpButtonListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
goToSignupActivity();
}
}; View.OnClickListener onClickForgotPasswordTextViewListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(LoginActivity.this);
builder.setTitle("Waraing");
builder.setIcon(R.drawable.ic_error);
builder.setMessage("Not implement");
builder.setPositiveButton("OK",null);
builder.show();
}
}; UserService.LoginListener loginListener = new UserService.LoginListener() {
@Override
public void onResponce(boolean loggedin, String message, User user) {
progressDialog.dismiss();
Toast.makeText(LoginActivity.this,message,Toast.LENGTH_SHORT).show();
if(loggedin)
{
SharedPreferences sharedPreferences = getSharedPreferences("user_data",MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
if(rememberMeCheckBox.isChecked())
{
editor.putBoolean("remembered", true);
editor.putString("username", user.getUsername());
editor.putString("password", user.getPassword());
}
else
{
editor.putBoolean("remembered",false);
editor.remove("username");
editor.remove("password");
}
editor.commit();
goToWelcomeActivity();
}
}
};
}

SignUpActivity 要向SignupActivity添加逻辑,您需要首先获取所有视图实例。 隐藏,收缩,复制Code

private ImageView profileImageView;
private EditText usernameEditText;
private EditText passwordEditText;
private EditText emailEditText;
private RadioGroup genderRadioGroup;
private RadioButton maleRadioButton;
private RadioButton femaleRadioButton;
private CompoundButton newsletterSubscriptionCompoundButton;
private CompoundButton allowOtherEmailCompoundButton;
private ProgressDialog progressDialog; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sign_up); progressDialog = new ProgressDialog(this);
progressDialog.setIndeterminate(true); profileImageView = (ImageView) findViewById(R.id.imageview_profile);
usernameEditText = (EditText) findViewById(R.id.edittext_username);
passwordEditText = (EditText) findViewById(R.id.edittext_password);
emailEditText = (EditText) findViewById(R.id.edittext_email);
genderRadioGroup = (RadioGroup) findViewById(R.id.radiogroup_gender);
maleRadioButton = (RadioButton) findViewById(R.id.radiobutton_male);
femaleRadioButton = (RadioButton) findViewById(R.id.radiobutton_female);
newsletterSubscriptionCompoundButton = (CompoundButton) findViewById(R.id.switch_subscription);
if(newsletterSubscriptionCompoundButton == null)
{
newsletterSubscriptionCompoundButton = (CompoundButton) findViewById(R.id.checkbox_subscription);
}
allowOtherEmailCompoundButton = (CompoundButton) findViewById(R.id.switch_allow_email);
if(allowOtherEmailCompoundButton == null) {
allowOtherEmailCompoundButton = (CompoundButton) findViewById(R.id.checkbox_allow_email);
}
}

我使用CompoundButton而不是Switch或复选框,因为我需要同时支持它们。 通过将其中一个选项设置为默认选项,以确保选中了一个性别按钮 隐藏,复制Code

@Override
protected void onCreate(Bundle savedInstanceState) {
...
maleRadioButton.setChecked(true);
}

当用户点击配置文件imageView时,我想允许他们选择他/她的设备上的图片。 隐藏,复制Code

private static final int SELECT_PICTURE = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
profileImageView.setOnClickListener(onClickProfileImageViewListener);
} View.OnClickListener onClickProfileImageViewListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
chooseImage();
}
}; private void chooseImage()
{
Intent intent = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, SELECT_PICTURE);
}

我使用Intent打开了另一个提供图像的应用程序。 当图像被接收时,我们将调整大小并设置在配置文件ImageView中显示它。 隐藏,收缩,复制Code

private Bitmap bitmap;
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == SELECT_PICTURE && resultCode == Activity.RESULT_OK)
try {
// We need to recyle unused bitmaps
if (bitmap != null) {
bitmap.recycle();
}
InputStream stream = getContentResolver().openInputStream(data.getData());
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize=2;
bitmap = BitmapFactory.decodeStream(stream, null, options);
int width = bitmap.getWidth();
int height = bitmap.getHeight();
double scale = 100.0/height;
height = (int)(height*scale);
width = (int)(width*scale);
bitmap = Bitmap.createScaledBitmap(bitmap, width,height, false);
stream.close();
profileImageView.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
super.onActivityResult(requestCode, resultCode, data);
}

接下来,当用户单击Submit Action菜单时,数据将发送到UserService以创建帐户。 隐藏,收缩,复制Code

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.sign_up, menu);
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_submit) {
String username = usernameEditText.getText().toString();
String password = passwordEditText.getText().toString();
String email = emailEditText.getText().toString();
User.Gender gender;
if(genderRadioGroup.getCheckedRadioButtonId() == R.id.radiobutton_male)
{
gender = User.Gender.MALE;
}
else
{
gender = User.Gender.FEMALE;
}
boolean newsletterSubscribed = newsletterSubscriptionCompoundButton.isChecked();
boolean allowedOtherEmail = allowOtherEmailCompoundButton.isChecked(); register(username,password,email,gender,newsletterSubscribed,allowedOtherEmail); return true;
}
return super.onOptionsItemSelected(item);
} private void register(String username,String password, String email, User.Gender gender, boolean newsletterSubscribed, boolean allowedOtherEmail)
{
progressDialog.show();
UserService.getInstance(SignUpActivity.this).register(username,password,email,gender,newsletterSubscribed,allowedOtherEmail,registerListener,bitmap);
}

实现用于接收注册结果的RegisterListener。 隐藏,复制Code

UserService.RegisterListener registerListener = new UserService.RegisterListener() {
@Override
public void onResponce(boolean registered, String message, User user) {
progressDialog.dismiss();
Toast.makeText(SignUpActivity.this, message, Toast.LENGTH_SHORT).show();
if(registered)
{
goToWelcomeActivity();
}
}
}; private void goToWelcomeActivity()
{
Intent intent = new Intent(this,WelcomeActivity.class);
startActivity(intent);
finish();
}

之后,您需要检查用户进入该活动时的登录状态。 隐藏,复制Code

 protected void onCreate(Bundle savedInstanceState) {
....
if(UserService.getInstance(this).getCurrentUser()!=null)
{
goToWelcomeActivity();
}
....
}

这里是一个完整的源代码: 隐藏,收缩,复制Code

package me.vable.android.viewandlayoutlessons;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Toast;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import me.vable.android.viewandlayoutlessons.data.User;
import me.vable.android.viewandlayoutlessons.data.service.UserService; public class SignUpActivity extends ActionBarActivity { private ImageView profileImageView;
private EditText usernameEditText;
private EditText passwordEditText;
private EditText emailEditText;
private RadioGroup genderRadioGroup;
private RadioButton maleRadioButton;
private RadioButton femaleRadioButton;
private CompoundButton newsletterSubscriptionCompoundButton;
private CompoundButton allowOtherEmailCompoundButton;
private ProgressDialog progressDialog;
private Bitmap bitmap; private static final int SELECT_PICTURE = 1; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sign_up); if(UserService.getInstance(this).getCurrentUser()!=null)
{
goToWelcomeActivity();
} progressDialog = new ProgressDialog(this);
progressDialog.setIndeterminate(true); profileImageView = (ImageView) findViewById(R.id.imageview_profile);
usernameEditText = (EditText) findViewById(R.id.edittext_username);
passwordEditText = (EditText) findViewById(R.id.edittext_password);
emailEditText = (EditText) findViewById(R.id.edittext_email);
genderRadioGroup = (RadioGroup) findViewById(R.id.radiogroup_gender);
maleRadioButton = (RadioButton) findViewById(R.id.radiobutton_male);
femaleRadioButton = (RadioButton) findViewById(R.id.radiobutton_female);
newsletterSubscriptionCompoundButton = (CompoundButton) findViewById(R.id.switch_subscription);
if(newsletterSubscriptionCompoundButton == null)
{
newsletterSubscriptionCompoundButton = (CompoundButton) findViewById(R.id.checkbox_subscription);
}
allowOtherEmailCompoundButton = (CompoundButton) findViewById(R.id.switch_allow_email);
if(allowOtherEmailCompoundButton == null) {
allowOtherEmailCompoundButton = (CompoundButton) findViewById(R.id.checkbox_allow_email);
}
maleRadioButton.setChecked(true); profileImageView.setOnClickListener(onClickProfileImageViewListener); } View.OnClickListener onClickProfileImageViewListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
chooseImage();
}
}; private void chooseImage()
{
Intent intent = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, SELECT_PICTURE);
} @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == SELECT_PICTURE && resultCode == Activity.RESULT_OK)
try {
// We need to recyle unused bitmaps
if (bitmap != null) {
bitmap.recycle();
}
InputStream stream = getContentResolver().openInputStream(data.getData());
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize=2;
bitmap = BitmapFactory.decodeStream(stream, null, options);
int width = bitmap.getWidth();
int height = bitmap.getHeight();
double scale = 100.0/height;
height = (int)(height*scale);
width = (int)(width*scale);
bitmap = Bitmap.createScaledBitmap(bitmap, width,height, false);
stream.close();
profileImageView.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
super.onActivityResult(requestCode, resultCode, data);
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.sign_up, menu);
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_submit) {
String username = usernameEditText.getText().toString();
String password = passwordEditText.getText().toString();
String email = emailEditText.getText().toString();
User.Gender gender;
if(genderRadioGroup.getCheckedRadioButtonId() == R.id.radiobutton_male)
{
gender = User.Gender.MALE;
}
else
{
gender = User.Gender.FEMALE;
}
boolean newsletterSubscribed = newsletterSubscriptionCompoundButton.isChecked();
boolean allowedOtherEmail = allowOtherEmailCompoundButton.isChecked(); register(username,password,email,gender,newsletterSubscribed,allowedOtherEmail); return true;
}
return super.onOptionsItemSelected(item);
} private void register(String username,String password, String email, User.Gender gender, boolean newsletterSubscribed, boolean allowedOtherEmail)
{
progressDialog.show();
UserService.getInstance(SignUpActivity.this).register(username,password,email,gender,newsletterSubscribed,allowedOtherEmail,registerListener,bitmap);
} UserService.RegisterListener registerListener = new UserService.RegisterListener() {
@Override
public void onResponce(boolean registered, String message, User user) {
progressDialog.dismiss();
Toast.makeText(SignUpActivity.this, message, Toast.LENGTH_SHORT).show();
if(registered)
{
goToWelcomeActivity();
}
}
}; private void goToWelcomeActivity()
{
Intent intent = new Intent(this,WelcomeActivity.class);
startActivity(intent);
finish();
}
}

受欢迎的活动 此活动将只显示使用配置文件图像和问候消息。 你需要获取视图上的instace并设置它们的值。 隐藏,复制Code

private ImageView profileImageView;
private TextView greetingTextView; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome); profileImageView = (ImageView) findViewById(R.id.imageview_profile);
greetingTextView = (TextView) findViewById(R.id.textview_greeting); greetingTextView.setText(String.format("Hello, %s", user.getUsername()));
profileImageView.setImageBitmap(UserService.getInstance(this).getProfileImage(user));
}

检查用户实例。如果它不存在,您应该立即关闭此活动。 隐藏,复制Code

User user = UserService.getInstance(this).getCurrentUser();

if(user==null) {
finish();
return;
}

然后,使用onOptionsItemSelected()方法检测选项菜单项单击事件,并为每个事件创建操作。 隐藏,收缩,复制Code

    @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.welcome, menu);
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.menu_user_list) {
return true;
}else if (id == R.id.menu_profile) {
goToMenuProfilePage();
return true;
}else if (id == R.id.menu_logout) {
logout();
return true;
}
return super.onOptionsItemSelected(item);
} private void goToMenuProfilePage()
{
Intent intent = new Intent(this,ProfileActivity.class);
startActivity(intent);
} private void logout()
{
UserService.getInstance(this).logout();
SharedPreferences sharedPreferences = getSharedPreferences("user_data",MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean("remembered",false);
editor.remove("username");
editor.remove("password");
editor.commit();
finish();
}
}

在goToMenuProfilePage()中,我有cr关闭意图并将额外的数据放入其中,因为我想要将User对象传递到ProfileActivity中。 这里是一个完整的源代码: 隐藏,收缩,复制Code

package me.vable.android.viewandlayoutlessons;

import android.content.Intent;
import android.content.SharedPreferences;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.TextView;
import me.vable.android.viewandlayoutlessons.data.User;
import me.vable.android.viewandlayoutlessons.data.service.UserService; public class WelcomeActivity extends ActionBarActivity { private ImageView profileImageView;
private TextView greetingTextView; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome); profileImageView = (ImageView) findViewById(R.id.imageview_profile);
greetingTextView = (TextView) findViewById(R.id.textview_greeting); User user = UserService.getInstance(this).getCurrentUser(); if(user==null) {
finish();
return;
} greetingTextView.setText(String.format("Hello, %s", user.getUsername()));
profileImageView.setImageBitmap(UserService.getInstance(this).getProfileImage(user));
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.welcome, menu);
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.menu_user_list) {
return true;
}else if (id == R.id.menu_profile) {
goToMenuProfilePage();
return true;
}else if (id == R.id.menu_logout) {
logout();
return true;
}
return super.onOptionsItemSelected(item);
} private void goToMenuProfilePage()
{
Intent intent = new Intent(this,ProfileActivity.class);
startActivity(intent);
} private void logout()
{
UserService.getInstance(this).logout();
SharedPreferences sharedPreferences = getSharedPreferences("user_data",MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean("remembered",false);
editor.remove("username");
editor.remove("password");
editor.commit();
finish();
}
}

概要文件的活动 ProfileActivity将从intent接收用户对象,并在屏幕上显示用户信息。首先,我们需要从intent接收User对象并获取所有视图实例。 隐藏,收缩,复制Code

private ImageView profileImageView;
private TextView usernameTextView;
private TextView emailTextVIew;
private TextView genderTextView;
private CompoundButton newsletterSubscriptionCompoundButton;
private CompoundButton allowOtherEmailCompoundButton; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile); User user = (User) getIntent().getExtras().getSerializable("user"); if(user==null) {
finish();
return;
} profileImageView = (ImageView) findViewById(R.id.imageview_profile);
usernameTextView = (TextView) findViewById(R.id.textview_username);
emailTextVIew = (TextView) findViewById(R.id.textview_email);
genderTextView = (TextView) findViewById(R.id.textview_gender);
newsletterSubscriptionCompoundButton = (Switch) findViewById(R.id.switch_subscription);
if(newsletterSubscriptionCompoundButton==null)
{
newsletterSubscriptionCompoundButton = (CheckBox) findViewById(R.id.checkbox_subscription);
}
allowOtherEmailCompoundButton = (Switch) findViewById(R.id.switch_allow_email);
if(allowOtherEmailCompoundButton==null)
{
allowOtherEmailCompoundButton = (CheckBox) findViewById(R.id.checkbox_allow_email);
}
}

接下来,将该值设置为视图 隐藏,复制Code

profileImageView.setImageBitmap(UserService.getInstance(this).getProfileImage(user));
usernameTextView.setText(String.format("Username: %s",user.getUsername()));
emailTextVIew.setText(String.format("Email: %s",user.getEmail()));
genderTextView.setText(String.format("Gender: %s",user.getGender()== User.Gender.MALE?"Male":"Female"));
newsletterSubscriptionCompoundButton.setChecked(user.isNewsletterSubscribed());
allowOtherEmailCompoundButton.setChecked(user.isAllowedOtherEmail());

最后,如果allowOtherEmailCompoundButton没有被选中,我们需要隐藏电子邮件。 隐藏,复制Code

if(!allowOtherEmailCompoundButton.isChecked())
{
emailTextVIew.setVisibility(View.GONE);
}

这里是一个完整的源代码: 隐藏,收缩,复制Code

package me.vable.android.viewandlayoutlessons;

import android.app.Activity;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.Switch;
import android.widget.TextView; import org.w3c.dom.Text; import me.vable.android.viewandlayoutlessons.data.User;
import me.vable.android.viewandlayoutlessons.data.service.UserService; public class ProfileActivity extends ActionBarActivity { private ImageView profileImageView;
private TextView usernameTextView;
private TextView emailTextVIew;
private TextView genderTextView;
private CompoundButton newsletterSubscriptionCompoundButton;
private CompoundButton allowOtherEmailCompoundButton; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile); User user = (User) getIntent().getExtras().getSerializable("user"); if(user==null) {
finish();
return;
} profileImageView = (ImageView) findViewById(R.id.imageview_profile);
usernameTextView = (TextView) findViewById(R.id.textview_username);
emailTextVIew = (TextView) findViewById(R.id.textview_email);
genderTextView = (TextView) findViewById(R.id.textview_gender);
newsletterSubscriptionCompoundButton = (Switch) findViewById(R.id.switch_subscription);
if(newsletterSubscriptionCompoundButton==null)
{
newsletterSubscriptionCompoundButton = (CheckBox) findViewById(R.id.checkbox_subscription);
}
allowOtherEmailCompoundButton = (Switch) findViewById(R.id.switch_allow_email);
if(allowOtherEmailCompoundButton==null)
{
allowOtherEmailCompoundButton = (CheckBox) findViewById(R.id.checkbox_allow_email);
} profileImageView.setImageBitmap(UserService.getInstance(this).getProfileImage(user));
usernameTextView.setText(String.format("Username: %s",user.getUsername()));
emailTextVIew.setText(String.format("Email: %s",user.getEmail()));
genderTextView.setText(String.format("Gender: %s",user.getGender()== User.Gender.MALE?"Male":"Female"));
newsletterSubscriptionCompoundButton.setChecked(user.isNewsletterSubscribed());
allowOtherEmailCompoundButton.setChecked(user.isAllowedOtherEmail()); if(!allowOtherEmailCompoundButton.isChecked())
{
emailTextVIew.setVisibility(View.GONE);
}
}
}

用户列表活动,应用程序的最后一个活动 这是一篇关于视图和ViewGroup的文章,但是如果不编写代码,您将无法理解此活动中的ViewGroup。这就是我用这个活动结束这篇文章的原因,ViewGroup是ListView,每个应用程序的通用视图。 列表视图 大多数应用程序在Play Store都有一个ListView, ListView的基本思想是管理一系列的数据,当数据被用户动态创建时,你永远不会知道它的大小。ListView是最好的解决方案,您只为单个数据创建模板视图,适配器将应用每个数据项到视图并自动排列到列表中。 ListView是一个视图容器(ViewGroup),它不是一个布局,你不能把项目直接放在ListView上,但你需要创建一个适配器,就像一个中间件提供的视图项目到ListView。 上面的图片显示了ListView是如何工作的,适配器将使用数据并创建视图(列表项),然后将其提供给ListView。 的机制 当你添加适配器到ListView, ListView会要求数据源中的一些数据项,然后ListView会要求在特定位置需要显示在屏幕上的数据项的视图。每当数据源更改后,此过程将重新运行。 注意:ListView每次只存储n+1个项目,其中n是ListView在单个屏幕上不滚动就能显示的最大项目数。 基本项目的MainActivity就是一个很好的例子,看看MainActivity的布局,你只会看到一个ListView。 隐藏,复制Code

<ListViewxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:id="@android:id/list"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity">

</ListView>

然后查看MainActivity Java代码,您将看到ActivityData实例的集合。 隐藏,收缩,复制Code

List<ActivityData> activityDataList = new ArrayList<ActivityData>();//List of the ActivityData instance, put you ActivityData here
activityDataList.add(new ActivityData("Login",LoginActivity.class));
activityDataList.add(new ActivityData("Welcome",WelcomeActivity.class));
activityDataList.add(new ActivityData("Sign up Activity",SignUpActivity.class));
activityDataList.add(new ActivityData("Profile Activity",ProfileActivity.class));
activityDataList.add(new ActivityData(getString(R.string.title_activity_sample_inflate_view_from_xml),SampleInflateViewFromXmlActivity.class));//add the ActivityData to the List
activityDataList.add(new ActivityData(getString(R.string.title_activity_sample_create_view_in_java_code),SampleCreateViewInJavaCodeActivity.class));
activityDataList.add(new ActivityData("My Fist Activity",MyFirstActivity.class));
activityDataList.add(new ActivityData("TextView Example",TextViewExampleActivity.class));
activityDataList.add(new ActivityData("EditText Example",EditTextExampleActivity.class));
activityDataList.add(new ActivityData("ImageView Example",ImageViewExampleActivity.class));
activityDataList.add(new ActivityData("Button Example",ButtonExampleActivity.class));
activityDataList.add(new ActivityData("CheckBox Example",CheckBoxExampleActivity.class));
activityDataList.add(new ActivityData("LinearLayout Example",LinearLayoutExampleActivity.class));
activityDataList.add(new ActivityData("RelativeLayout Example",RelativeLayoutExampleActivity.class));
activityDataList.add(new ActivityData("Options Menu Example",OptionsMenuExampleActivity.class));
activityDataList.add(new ActivityData("Radio Button Example",RadioButtonExampleActivity.class));
activityDataList.add(new ActivityData("Switch Example",SwitchExampleActivity.class));

ActivityData成员: 将在ListView上显示的标题。ActivityClass——用于打开活动的activity类。 我想在ListView上显示这个集合,适配器是我需要的东西。要创建适配器,您需要创建BaseAdapter类。 这些是你需要重写的适配器方法: getCount()—数据源(或集合)中的项数。getItem()——返回特定位置的数据项。getItemId() -返回数据项在特定位置的id。getView() -返回数据项在特定位置的视图实例。 在ActivityDataListAdapter中,我创建了使用上下文和ActivityData集合作为参数的构造。 隐藏,复制Code

public class ActivityDataListAdapter extends BaseAdapter {

    private Context mContext;
private List<ActivityData> mItems; public ActivityDataListAdapter(Context context,List<ActivityData> items)
{
mContext = context;
mItems = items;
} ... }

然后我创建了用于管理集合的方法。 隐藏,复制Code

public void add(ActivityData activityData)
{
mItems.add(activityData);
notifyDataSetChanged();
} public void addAll(List<ActivityData> items)
{
mItems.addAll(items);
notifyDataSetChanged();
} public void remove(int index)
{
mItems.remove(index);
notifyDataSetChanged();
} public void remove(ActivityData activityData)
{
mItems.remove(activityData);
notifyDataSetChanged();
}

注意:notifyDataSetChanged()方法用于请求ListView重新设置。您需要在数据源中添加、删除、编辑项之后调用它。 getCount()方法将返回数据源大小。 隐藏,复制Code

@Override
public int getCount() {
return mItems.size();
}

getItem()方法将返回位于特定位置的数据项 隐藏,复制Code

@Override
public ActivityData getItem(int i) {
return mItems.get(i);
}

我们的数据没有id属性,在getItemId()方法中只返回一个0。 隐藏,复制Code

@Override
public long getItemId(int i) {
return 0;
}

然后我需要创建在getView()方法中使用的视图。我已经创建了一个视图,包含2 TextView,第一个为标题和另一个活动类名。 listitem_activity_data.xml: 隐藏,收缩,复制Code

<?xmlversion="1.0"encoding="utf-8"?>

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:padding="8dp">

    <TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:textAppearance="?android:attr/textAppearanceLarge"android:text="@string/listitem_textview_default_activity_title"android:id="@+id/textview_title"android:padding="8dp"/>

    <TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:textAppearance="?android:attr/textAppearanceSmall"android:text="@string/listitem_textview_activity_class_name"android:id="@+id/textview_class"android:padding="8dp"/>
</LinearLayout>

注意:列表项布局的名称应该以单词“listitem”开头。 然后,重写getView()方法 隐藏,收缩,复制Code

@Override
public View getView(int i, View view, ViewGroup viewGroup) { if(view == null)
{
view = LayoutInflater.from(mContext).inflate(R.layout.listitem_activity_data,null);
} ActivityData activityData = getItem(i); String title = activityData.getTitle();
Class clazz = activityData.getActivityClass(); TextView titleTextView = (TextView)view.findViewById(R.id.textview_title);
TextView classTextView = (TextView)view.findViewById(R.id.textview_class); if(title==null)
titleTextView.setText(mContext.getString(R.string.listitem_textview_default_activity_title));
else
titleTextView.setText(title); if(clazz==null)
classTextView.setText(mContext.getString(R.string.listitem_textview_activity_class_name));
else
classTextView.setText(clazz.getSimpleName()); return view;
}

getView()方法中有整数、视图和ViewGroup参数,第一个参数是当前位置,第二个是当前项目的视图,第三个是ListView实例。首先,我检查一个视图实例是否不存在,膨胀一个新的,然后在特定位置获取项目,获取视图实例并设置数据。 回到MainActivity Java cocde,创建ActivityDataListAdapter的实例,并将其设置为ListView。 隐藏,复制Code

ActivityDataListAdapter activityDataListAdapter = new ActivityDataListAdapter(this,activityDataList);
ListView listView = (ListView)findViewById(android.R.id.list);
listView.setAdapter(activityDataListAdapter);

当你运行应用程序时,你会看到像这样的ActivityData列表。 现在,通过实现OnItemC,在用户单击列表项时添加操作lickListener。 隐藏,收缩,复制Code

AdapterView.OnItemClickListener onItemClickListener = new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
ActivityData activityData = (ActivityData)adapterView.getAdapter().getItem(i);//get the selected item from the Adapter
if(activityData.getActivityClass()!=null)
{
try{
Intent intent = new Intent(MainActivity.this, activityData.getActivityClass());//create the intent for start the new Activity
startActivity(intent);//start the new Activity
}
catch(ActivityNotFoundException e)//Activity not found or the class that you provide is not an Activity
{
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);//Create alert dialog builder
builder.setIcon(R.drawable.ic_error);//set dialog icon to drawable resource
builder.setTitle(R.string.error_dialog_title);//set dialog title
builder.setMessage(
String.format(
getString(R.string.error_dialog_activity_not_found_message),
activityData.getActivityClass().getSimpleName()
)
);//set dialog message
builder.setPositiveButton(android.R.string.ok,null);//set positive button title and action
builder.show();//show the dialog
}
}
}
};

这个OnItemClickListener实例将把用户带到他/她选择的活动,或者如果没有发现活动,将显示错误。 然后设置ListView在项目被点击时调用这个监听器。 隐藏,复制Code

    @Override
    protected void onCreate(Bundle savedInstanceState) {
...
listView.setOnItemClickListener(onItemClickListener);
}

完成! ! 熟悉的视图:GridView, Spinner。 创建UserListActivity 现在,您已经了解了ListView和适配器。提示您创建UserListActivity,让我们现在开始吧!! 首先,您需要创建活动和布局。然后将ListView添加到布局文件中。 隐藏,复制Code

<ListViewxmlns: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="me.vable.android.viewandlayoutlessons.UserListActivity"android:id="@android:id/list">

</ListView>

其次,为用户项创建视图。 隐藏,收缩,复制Code

<?xmlversion="1.0"encoding="utf-8"?>

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:orientation="horizontal"android:layout_width="match_parent"android:layout_height="66dp">

    <ImageViewandroid:id="@+id/imageview_profile"android:src="@drawable/ic_man"android:layout_width="50dp"android:layout_height="50dp"android:adjustViewBounds="true"android:layout_margin="8dp"/>

    <TextViewandroid:id="@+id/textview_username"android:layout_gravity="center_vertical"android:text="Username"android:textSize="18sp"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_margin="8dp"/>

</LinearLayout>

第三,创建使用用户列表中的数据的适配器名称UserListAdapter。 隐藏,收缩,复制Code

package me.vable.android.viewandlayoutlessons.data.adapter;

import android.content.Context;
import android.media.Image;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView; import java.util.List; import me.vable.android.viewandlayoutlessons.R;
import me.vable.android.viewandlayoutlessons.data.User;
import me.vable.android.viewandlayoutlessons.data.service.UserService; /**
* Created by Varavut on 8/23/2014.
*/
public class UserListAdapter extends BaseAdapter { Context mContext;
List<User> mItems;
public UserListAdapter(Context context,List<User> users)
{
mContext = context;
mItems = users;
} @Override
public int getCount() {
return mItems.size();
} @Override
public User getItem(int i) {
return mItems.get(i);
} @Override
public long getItemId(int i) {
return 0;
} @Override
public View getView(int i, View view, ViewGroup viewGroup) {
if(view == null)
{
view = LayoutInflater.from(mContext).inflate(R.layout.listitem_user,null);
}
User user = getItem(i);
ImageView profileImageView = (ImageView)view.findViewById(R.id.imageview_profile);
TextView usernameTextView = (TextView)view.findViewById(R.id.textview_username); profileImageView.setImageBitmap(UserService.getInstance(mContext).getProfileImage(user));
usernameTextView.setText(user.getUsername());
return view;
}
}

接下来,从UserService获取用户列表,在UserListActivity java代码中创建UseListAdapter的实例,并将其设置为ListView。 以下是我的代码: 隐藏,收缩,复制Code

package me.vable.android.viewandlayoutlessons;

import android.app.Activity;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ListView; import java.util.ArrayList;
import java.util.List; import me.vable.android.viewandlayoutlessons.data.User;
import me.vable.android.viewandlayoutlessons.data.adapter.UserListAdapter;
import me.vable.android.viewandlayoutlessons.data.service.UserService; public class UserListActivity extends ActionBarActivity { List<User> users = new ArrayList<User>();
UserListAdapter adapter; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_list); adapter = new UserListAdapter(this, users); UserService.getInstance(this).getUserList(getUserListListener); ListView userListView = (ListView) findViewById(android.R.id.list);
userListView.setAdapter(adapter);
} UserService.GetUserListListener getUserListListener = new UserService.GetUserListListener() {
@Override
public void onResponce(boolean success, String message, List<User> userList) {
if(success)
{
users.clear();
adapter.notifyDataSetChanged();
users.addAll(userList);
adapter.notifyDataSetChanged();
}
}
};
}

当用户点击列表项时,应用程序将导航到UserProfileActivity。 隐藏,复制Code

@Override
protected void onCreate(Bundle savedInstanceState) {
...
userListView.setOnItemClickListener(onItemClickListener);
} AdapterView.OnItemClickListener onItemClickListener = new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Intent intent = new Intent(UserListActivity.this,ProfileActivity.class);
intent.putExtra("user",adapter.getItem(i));
startActivity(intent);
}
};

最后,回到WelcomeActivity,这里有一个没有操作的用户列表菜单。添加用于打开UserListActivity的操作。 隐藏,复制Code

@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.menu_user_list) {
goToUserListPage();
return true;
}else if (id == R.id.menu_profile) {
goToMenuProfilePage();
return true;
}else if (id == R.id.menu_logout) {
logout();
return true;
}
return super.onOptionsItemSelected(item);
} private void goToUserListPage()
{
Intent intent = new Intent(this,UserListActivity.class);
startActivity(intent);
}

运行应用程序并尝试使用每个函数!! 完整的项目存储库 ViewAndLayoutLessons GitHub上 的兴趣点 Android提供了许多基本视图和ViewGroup组件,而且你可以创建自己的自定义视图和复合视图。这篇文章只是Android视图系统的一小部分,还有更多的视图需要你学习。跳你enjou你的Android应用开发者生活!! 历史 24/08/2014初始提交。 24/08/2014添加熟悉的视图信息。 24/08/2014更正拼写错误的单词 25/08/2014更正设备信息 本文转载于:http://www.diyabc.com/frontweb/news30348.html

让我们创建屏幕- Android UI布局和控件的更多相关文章

  1. Flutter学习指南:UI布局和控件

    Flutter学习指南:UI布局和控件 - IT程序猿  https://www.itcodemonkey.com/article/11041.html

  2. Android常用布局和控件

    一.Android常用布局属性 1. LinearLayout的特有属性 android:orientation:设置布局排列方式   android:layout_weight:设置所占布局的权重  ...

  3. Android UI学习1:控件和基本事件的响应

    在任何一个 GUI 系统中,控制界面上的控件(通常称为控件)都是一个基本的内容.对于 Android 应用程序,控件称为 View. 在 Android 中,在处理 UI 中的各种元素的时候,两个程序 ...

  4. Android UI组件----AppWidget控件入门详解

    Widget引入 我们可以把Widget理解成放置在桌面上的小组件(挂件),有了Widget,我们可以很方便地直接在桌面上进行各种操作,例如播放音乐. 当我们长按桌面时,可以看到Widget选项,如下 ...

  5. Android 简单布局、控件

    布局 线性布局 LinearLayout <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android ...

  6. Android UI 之TextView控件属性列表

    在网上收集到了TextView 的属性,在开发过程中还是挺有用的. android:autoLink 设置是否当文本为URL链接/email/电话号码/map时,文本显示为可点击的链接.可选值(non ...

  7. Android UI -- 布局介绍(布局包括FrameLayout, LinearLayout, RelativeLayout, GridLayout)

    首先介绍常用布局类 FrameLayout 最简单的布局管理器. 这个布局管理类有几个特性: 添加组件默认在左上角的. 如果添加多个组件会叠加到一起,并且都在左上角.(可以通过一gravity属性改变 ...

  8. Android开发之基本控件和详解四种布局方式

    Android中的控件的使用方式和iOS中控件的使用方式基本相同,都是事件驱动.给控件添加事件也有接口回调和委托代理的方式.今天这篇博客就总结一下Android中常用的基本控件以及布局方式.说到布局方 ...

  9. Android 在程序中动态添加 View 布局或控件

    有时我们需要在程序中动态添加布局或控件等,下面用程序来展示一下相应的方法: 1.addView 添加View到布局容器 2.removeView 在布局容器中删掉已有的View 3.LayoutPar ...

随机推荐

  1. 使用easyexcel时遇到Could not initialize class net.sf.cglib.beans.BeanMap$Generator

    可以访问 这里 查看更多关于大数据平台建设的原创文章. 上一篇文章 Maven项目为什么会产生NoClassDefFoundError的jar包冲突 结合了大量的图解,详细介绍了Maven项目产生ja ...

  2. zabbix-4.0-监控服务器的ping告警设置

    问题:一直在困惑如果一台服务器的网络发生故障或者断开时,怎么第一时间发现并去排查. 思路:利用zabbix平台监控服务器,监控ping这一项,设置一个报警,并使用脚本去提醒与通知,可使用邮件报警/短信 ...

  3. 极简显示sessionid的jsp程序 war下载

    下载地址:https://files.cnblogs.com/files/xiandedanteng/simpleJspSessionId20200103.zip 解压后得到myweb.war就是可以 ...

  4. Nginx升级加固SSL/TLS协议信息泄露漏洞(CVE-2016-2183)

    Nginx升级加固SSL/TLS协议信息泄露漏洞(CVE-2016-2183) 漏洞说明 // 基于Nginx的https网站被扫描出SSL/TLS协议信息泄露漏洞(CVE-2016-2183),该漏 ...

  5. 架构设计 | 基于Seata中间件,微服务模式下事务管理

    源码地址:GitHub·点这里 || GitEE·点这里 一.Seata简介 1.Seata组件 Seata是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务.Seata将为用 ...

  6. loadrunner跑场景时报错Full MDB file. New error messages will be ignored

    这个原因是在controller跑场景时,controller的日志文件占用内存太大 解决办法:先找到controller的日志文件Results——Results Setting——找到日志的路径, ...

  7. 吴恩达《深度学习》-第一门课 (Neural Networks and Deep Learning)-第三周:浅层神经网络(Shallow neural networks) -课程笔记

    第三周:浅层神经网络(Shallow neural networks) 3.1 神经网络概述(Neural Network Overview) 使用符号$ ^{[

  8. [Leetcode]148. 排序链表(归并排序)

    题目 在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序. 示例 1: 输入: 4->2->1->3 输出: 1->2->3->4 示例 2: ...

  9. [程序员代码面试指南]第9章-在两个长度相等的排序数组中找到第k小的数(二分)

    题目 给定两个有序数组arr1和arr2,再给定一个整数k,返回所有的数中第k小的数. 题解 利用题目"在两个长度相等的排序数组中找到第上中位数"的函数 分类讨论 k < 1 ...

  10. k8s滚动更新(六)

    实践 滚动更新是一次只更新一小部分副本,成功后,再更新更多的副本,最终完成所有副本的更新.滚动更新的最大的好处是零停机,整个更新过程始终有副本在运行,从而保证了业务的连续性. 下面我们部署三副本应用, ...