文章给大家介绍Android 组件开发之带label的文本输入框(EditText),有需要了解的朋友可参考,希望此教程对各位有所帮助。
在Android开发中,我们的Activity都不免要用到很多的View部件,而对于每一个View我们都要findViewById,设置监听器,获取用户输入的结果等操作。如果我们细心想想,这些琐碎的操作是不是跟这个Activity的处理逻辑没有很大的关系呢?很多的Activity中都要用到一些常见的View组合,能不能把他们抽象出来形成一种可以复用的复合组件呢?
这篇文章就是基于这种想法,开发了一个简单的组件,对于Android新手来说,可以作为一种参考吧。
EditTextWithLabel组件类定义:(EditTextWithLabel.java)
代码如下 |
复制代码 |
package com.raysmond.component;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
public class EditTextWithLabel extends LinearLayout{
TextView label;
EditText text;
public EditTextWithLabel(Context context,AttributeSet attrs){
super(context, attrs);
setOrientation(HORIZONTAL);
LayoutInflater.from(context).inflate(R.layout.edit_text_with_label, this, true);
label = (TextView) findViewById(R.id.comp_le_label);
text = (EditText) findViewById(R.id.comp_le_content);
}
public boolean setSubViewFocus(){
return text.requestFocus();
}
public EditText getEditText(){
return text;
}
public String getContent(){
return text.getText().toString();
}
public void setContent(String str){
text.setText(str);
}
public void setError(String error){
text.setError(error);
}
}
|
EditTextWithLabel组件的布局xml(edit_text_with_label.xml)
代码如下 |
复制代码 |
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:id="@+id/comp_le_label"
android:layout_width="wrap_content"
android:layout_weight="3"
android:layout_height="wrap_content"
android:paddingRight="5dp"
android:text="Label"
android:textSize="25sp"
android:gravity="center"/>
<EditText
android:inputType="text"
android:id="@+id/comp_le_content"
android:layout_width="wrap_content"
android:layout_weight="7"
android:layout_height="wrap_content"
android:textSize="25sp"
>
<requestFocus />
</EditText>
</merge>
|
使用EditTextWithLabel复合组件,主Activity的XML (activity_main.xml)
代码如下 |
复制代码 |
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:layout_width="wrap_content"
android:id="@+id/hello_world"
android:layout_height="wrap_content"
android:textSize="28sp"
android:text="带Label的输入框组件" />
<com.raysmond.component.EditTextWithLabel
android:id="@+id/test_component"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/hello_world"
/>
</RelativeLayout>
|
使用EditTextWithLabel复合组件,主Activity类(MainActivity.java)
代码如下 |
复制代码 |
package com.raysmond.activity;
import com.raysmond.component.EditTextWithLabel;
import com.raysmond.component.R;
import android.os.Bundle;
import android.app.Activity;
public class MainActivity extends Activity {
EditTextWithLabel component;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findView();
}
public void findView(){
component = (EditTextWithLabel) findViewById(R.id.test_component);
component.setSubViewFocus();
}
}
|
Demo:
在Android开发中layout_weight属性是我们常用的一个属性了,layout_weight数值越小,所占空间越大,但尽可能大是有限度的,即fill_parent.
当控件本身layout_width设置为fill_parent的时候,layout_weight数值越小,所占空间越大,但尽可能大是有限度的,即fill_parent.
当控件本身layout_width设置为wrap_content的时候,layout_weight数值越小,所占空间也越小,但这个小是有限度的,即wrap_content.
例子
看了一下源码,虽说不太懂,但了解了下大概意思,按照自己的理解总结一下,直接写一下简化的代码吧(下面的代码是LinearLayout源文件中一部分的精简,变量名称含义可能不准确,为叙述方便暂作此解释):
代码如下 |
复制代码 |
//Either expand children with weight to take up available space or
// shrink them if they extend beyond our current bounds
int delta = widthSize - mTotalLength;
if (delta != 0 && totalWeight > 0.0f) {
float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;
for (int i = 0; i < count; ++i) {
final View child = getVirtualChildAt(i);
if (child == null || child.getVisibility() == View.GONE) {
continue;
}
final LinearLayout.LayoutParams lp =
(LinearLayout.LayoutParams) child.getLayoutParams();
float childExtra = lp.weight;
if (childExtra > 0) {
int share = (int) (childExtra * delta / weightSum);
weightSum -= childExtra;
delta -= share;
int childWidth = child.getMeasuredWidth() + share;
if (childWidth < 0) {
childWidth = 0;
}
}
}
}
|
变量含义
widthSize: LinearLayout的宽度
mTotalLength: 所有子View的宽度的和(还没用考虑layout_weight)
totalWeight: 所有子View的layout_weight的和
mWeihtSUm: LinearLayout的android:weightSum属性
过程分析:
首先计算出额外空间(可以为负)如果额外空间不为0并且有子View的layout_weight不为0的话按layout_weight分配额外空间:
代码如下 |
复制代码 |
int delta = widthSize - mTotalLength;
if (delta != 0 && totalWeight > 0.0f) {
...
}
|
如果LinearLayout设置了weightSum则覆盖子View的layout_weight的和:
代码如下 |
复制代码 |
float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;
|
然后遍历LinearLayout的子元素,如果不为null且Visibility不为GONE的话,取得它的LayoutParams,如果它的layout_weight大于0,根据weightSum与它的weight计算出分配给它的额外空间
代码如下 |
复制代码 |
if (childExtra > 0) {
int share = (int) (childExtra * delta / weightSum);
weightSum -= childExtra;
delta -= share;
int childWidth = child.getMeasuredWidth() + share;
if (childWidth < 0) {
childWidth = 0;
}
}
|
例子
代码如下 |
复制代码 |
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1">
<TextView
android:text="redwwwwwww"
android:gravity="center_horizontal"
android:background="#aa0000"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"/>
<TextView
android:text="green"
android:gravity="center_horizontal"
android:background="#00aa00"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="2"/>
<TextView
android:text="blue"
android:gravity="center_horizontal"
android:background="#0000aa"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="3"/>
<TextView
android:text="yellow"
android:gravity="center_horizontal"
android:background="#aaaa00"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="4"/>
</LinearLayout>
</LinearLayout>
|
本文章来给大家介绍Android 利用Application对象存取公共数据,有需要了解学习的同学不防进入参考。
Android系统在运行每一个程序应用的时候,都会创建一个Application对象,用于存储与整个应用相关的公共变量。一个Android应用只会生成一个Application对象,在不用的Activity中获取的Application对象是一样的,所以Application对象是一个单例(SingleTon)。Application对象非常适合用于存储一些与整个应用相关数据,例如应用版本,应用登录账户,数据缓存等。
利用Application对象存储公共数据或数据传递
在android开发中,activity的切换是很频繁的,差不多可以和一个网站中不同网页之间的切换一样。那么不同的activity之间需要存储公共信息(如只有一个当前登录用户)以及数据传递等。下面就是一种利用Application对象存储登录用户信息的方法,可以发现这很方便不同的activity获取登录用户信息。
首先,新建一个java类继承Application类:MyApplication.java
代码如下 |
复制代码 |
package com.example.applicationtest;
import android.app.Application;
public class MyApplication extends Application {
public String appVersion = "v1.0";
//当前登录用户
private User loginUser = new User();
public User getLoginUser(){
return loginUser;
}
public void userLogin(User user){
loginUser.setUserId(user.getUserId());
loginUser.setUserName(user.getUserName());
}
public void userLogout(){
loginUser = new User();
}
}
|
在AndroidManifest.xml中指定应用的application对象
代码如下 |
复制代码 |
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.applicationtest"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:name="com.example.applicationtest.MyApplication"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.applicationtest.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
|
在activity中使用application对象, 使用Activity的getApplication()方法。
代码如下 |
复制代码 |
package com.example.applicationtest;
import android.os.Bundle;
import android.app.Activity;
public class MainActivity extends Activity {
private MyApplication mApplication;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 获取整个应用的Application对象
// 在不同的Activity中获取的对象是同一个
mApplication = (MyApplication) getApplication();
}
/**
* 一般只有在登录界面中设置登录用户信息,在其他的Activity中
* 只要通过Application对象就可以获取登录用户信息
*/
private void login(){
User user = new User();
user.setUserId(1);
user.setUserName("Raysmond");
// 将登录用户信息保存到Application对象中
mApplication.userLogin(user);
}
}
|
可以发现通过Application对象,在不同的Activity之间可以方便地实现数据共享。这比在每次切换activity时通过Bundle传递数据方便多了。
传统的利用Bundle在activity之前传递数据的方式
假设我们有两个Activity: Activity1和Activity2,Activity1切换到Activity2并传递用户信息。
代码如下 |
复制代码 |
Activity1.java
package com.example.applicationtest;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
public class Activity1 extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_activity1);
// 切换到Activity2
gotoActivity2();
}
private void gotoActivity2(){
Intent intent = new Intent(Activity1.this,Activity2.class);
Bundle bundle = new Bundle();
bundle.putLong("USER_ID", 1);
bundle.putString("USER_NAME", "Raysmond");
intent.putExtras(bundle);
startActivity(intent);
}
}
Activity2.java
package com.example.applicationtest;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
public class Activity2 extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_activity2);
getUserInfo();
}
/**
* 从上一个Activity获取传递过来的数据
*/
private void getUserInfo(){
Intent intent = this.getIntent();
Bundle bundle = intent.getExtras();
long userId = bundle.getLong("USER_ID", -1L);
String userName = bundle.getString("USER_NAME");
}
}
|
我们可以发现这种传递数据的方式比较繁琐,特别是当Activity众多,切换很频繁的时候。整个应用的的公共数据(如登录信息)在不同的activity之间都一样且都需要用到时,利用Application对象更加简洁和方便
有很多朋友可能不知道iphone手机有二种方法可以实现快速给屏幕截图哦,下面我来给各位详细介绍。
方法一:快捷键截图
按动【Power】键+【Home】键,并快速松开,当你松手的瞬间会有“咔嚓”的拍照声出现,这时iphone屏幕上的画面就被捕捉下来,并保存到你的照片库中了。
方法二:Assistive Touch截图
“Assistive Touch”是ios系统自带的一个辅助功能,通过它可以降低对物理部件的损耗,尤其是“Home”键是较容易出现问题的。
开启Assistive Touch功能:
1.打开【设置】菜单,选择【通用】选项。2.继续点击“通用”里的【辅助功能】,将肢体活动版块中的【Assistive Touch】功能打开。
使用Assistive Touch截屏拍照:
安装好Assistive Touch后,你会在手机的屏幕上看到一个点状的新图案出现。 截屏步骤:1.点击这个【小点】,选择【设备】菜单,然后是【更多】选项。 2.这时在新界面中会有一个【屏幕快照】图标,点击后就能实现屏幕截图的效果。3. Assistive Touch的操作界面和屏幕界面是同时存在的,但截图效果中不会出现截图程序本身的操作画面。
方法三:iTools工具截图
1.将iphone5连接电脑,开启iTools工具。
2.点击侧边栏中的【桌面管理】,在右侧显示区的顶部会有个【实时桌面】功能,点击它。
3. 这时显示区的右侧中间位置会有一个“照相机”的图标,点击后就会将手机屏幕上的画面保存下来。
本文章来给大家介绍Android常见布局之线性布局一些实现程序,各位朋友可参考。
Android中比较常见的布局有线性布局(LinearLayout),表格布局(TableLayout),相对布局(RelativeLayout)及帧布局(FrameLayout)。
线性布局是将其中的组件按照线性的,以垂直或者水平方向来布局,组件的布局方向可由orientation属性来控制,其具体值有水平(horizontal)及垂直(vertical)。搞清楚布局以后,这玩意就的思考加练习,以各种方式在纸上进行画,或者在心里画,然后编写布局文件来练习,时间长了就自然而然的熟练了。
练习要求:
1、把屏幕分成2部分,上面一部分,下面一部分
2、上面部分分为4列
3、下面部分分为4行
OK,开始练习!(在Eclipse中建立项目测试Layout,修改其res目录下的layout目录中的main.xml文件)
第一步:考虑LinearLayout使用数目,并确定其方向,由于是分为上下两部分,所以最外层layout采用垂直方向布局,里面两个layout分别表示上下;
<?xml version="1.0" encoding="utf-8" ?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout> <!-- 上面部分 -->
</LinearLayout>
<LinearLayout> <!-- 下面部分 -->
</LinearLayout>
</LinearLayout>
第二步:补充内部layout属性及增加组件,这里用TextView组件来填充LinearLayout,不断补充调整,最终布局文件如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1">
<TextView
android:text="col1"
android:gravity="center_horizontal"
android:background="#999999"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1" />
<TextView
android:text="col2"
android:gravity="center_horizontal"
android:background="#290fc0"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1" />
<TextView
android:text="col3"
android:gravity="center_horizontal"
android:background="#999999"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1" />
<TextView
android:text="col4"
android:gravity="center_horizontal"
android:background="#290fc0"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1">
<TextView
android:text="row_one"
android:textSize="15sp"
android:background="#290fc0"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
<TextView
android:text="row_two"
android:textSize="15sp"
android:background="#999999"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
<TextView
android:text="row_three"
android:textSize="15sp"
android:background="#290fc0"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
<TextView
android:text="row_four"
android:textSize="15sp"
android:background="#999999"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout>
运行效果如下图所示:
LinearLayout
标签:[!--infotagslink--]