• 下载LifeCycleTest.zip - 278.9 KB
  • 下载ViewAndLayoutLessons_-_Base.zip - 1.2 MB
  • 下载ViewAndLayoutLessons_-_Completed.zip - 1.1 MB

指数 介绍背景,论述基础 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

@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);//set the activity_main.xml as screen content    List activityDataList = new ArrayList();//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 activityDataList = new ArrayList();//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

 android:text="Hello World"        android:textSize="36dp"        android:textColor="#FF0000"        android:fontFamily="serif"        />

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

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

您需要在活动中创建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_如果是动作菜单或menu_如果是正常的菜单。 我将创建一个关于菜单作为一个弹出菜单。 隐藏,复制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_ 选择选项后,单击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

@Overridepublic 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;}@Overridepublic 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

@Overridepublic 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 users);}

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

private EditText usernameEditText;private EditText passwordEduitText;private CheckBox rememberMeCheckBox;private TextView forgotPasswordTextView;private Button loginButton;private Button signUpButton;@Overrideprotected 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

@Overrideprotected 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

@Overrideprotected 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

@Overrideprotected 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;@Overrideprotected 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

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

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

private static final int SELECT_PICTURE = 1;@Overrideprotected 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;@Overrideprotected 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

@Overridepublic boolean onCreateOptionsMenu(Menu menu) {    getMenuInflater().inflate(R.menu.sign_up, menu);    return true;}@Overridepublic 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;@Overrideprotected 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;@Overrideprotected 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 hereactivityDataList.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 ListactivityDataList.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 mItems;    public ActivityDataListAdapter(Context context,List items)    {        mContext = context;        mItems = items;    }    ...}

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

public void add(ActivityData activityData){    mItems.add(activityData);    notifyDataSetChanged();}public void addAll(List 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

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

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

@Overridepublic 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

@Overridepublic 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 mItems;    public UserListAdapter(Context context,List 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 users = new ArrayList();    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 userList) {            if(success)            {                users.clear();                adapter.notifyDataSetChanged();                users.addAll(userList);                adapter.notifyDataSetChanged();            }        }    };}

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

@Overrideprotected 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

@Overridepublic 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

更多相关文章

  1. Android(安卓)软键盘使用总结
  2. Android解决CoordinatorLayout折叠布局RecyclerView最后一条数据
  3. 强烈推荐:Android完全自学从零开始
  4. 使用DrawerLayout实现侧滑栏
  5. android界面设计(一)侧边栏的两种实现方式
  6. 从任意位置加载XML布局
  7. android 动态修改菜单menu
  8. Android(安卓)API 中文 (53) —— BaseAdapter
  9. TextView设置中文粗体

随机推荐

  1. sqlserver 实现收缩数据库日志操作
  2. sqlserver查询去掉重复数据的实现
  3. 详解sql中exists和in的语法与区别
  4. SQL Server重置IDENTITY属性种子值操作
  5. 在SQLserver数据库之间进行传表和传数据
  6. 解析SQL Server中datetimeset转换datetim
  7. SQL判断是否"存在",还在用 count 操作?很
  8. sql server把退款总金额拆分到尽量少的多
  9. SQLServer设置客户端使用IP地址登录的图
  10. 浅析SQL Server授予了CREATE TABLE权限但