这几天被一些功能折磨的要死了,于是放下了这个,看点其它的东西,算是转移一下焦点。床头放了不少书籍,也都被翻阅过,翻阅过,却不曾细细的品味过,俗话说,书可借而不可买也,这话用到自己的身上丝毫不错。
因为是自己的书,所以看的不是那么的仔细,那么的认真,总觉得有的是机会,殊不知,这是一种病,一种正在侵蚀自己的病,不知道我此时醒悟,算不算是为时已晚。
从来没有仔细过,认真过,书中的东西也都草草而过,似懂非懂,而不深入,细节就这样被忽视,书的味道往往就藏在这些细腻而不起眼的文字中。这两天因为烦躁就看了下Android的东西,将自己的一些想法写下来,与大家分享。
关于view
View是什么了,view就像一个画板,让我们用自己的画笔在上面进行涂鸦。 其实说白了,View就是一个矩形区域并且负责界面绘制和事件处理,我们可以在这个区域上定义自己的控件。在Android中,View的生成往
往是通过布局文件来创建的,比如在继承Activity的类的onCreate里面使用setContentView方法来载入一个在xml里定义好的界面.Android的布局文件可以有很多个,很多的时候需要动态的载入,比如对于
PopupWidnow这对象来说,它显示的内容往往是动态载入的,LayoutInflater这个的作用就是如此。在Android可以用LayoutInflater inflater = LayoutInflater.from(context)和getSystemService
(Context.LAYOUT_INFLATER_SERVICE)获取。获取到LayoutInflater之后,然后调用inflate方法把一个没有被载入,或者想要动态载入的界面显示出来。
其实不管是setContentView()还是LayoutInflater.from()从源码中能够看出它们都是调用getSystemService()方法。获取到了View,那么如何将其显示出来了,稍微有点编程概念的人都知道,是需要通过Draw的,
这个是一个很复杂的过程,我也说不清,推荐一篇博客:http://www.incoding.org/admin/archives/179.html
关于Context
如果动态的创建一个控件,可以发现构造函数中有Context这个参数,Context字面意思上下文,位于framework package的android.content.Context中,其实该类为LONG型,类似Win32中的Handle句柄,Context提供
了关于应用环境全局信息的接口,控制着生命周期,Activity、Service以及BroadcastReceiver都是直接或者间接的继承了这个接口,所以在Activty中 传递的this往往指的是Context,不同的Context,生命周期是
不一样的,如getApplicationContext()取的是这个应用程序的Context,Activity.this取的是这个Activity的Context,这两者的生命周期是不同的,前者的生命周期是整个应用,后者的生命周期只是它所在的
Activity。比如Toast.makeText方法的第一个参数就是Context,一般在Activity中我们直接用this代替,该是属于一个Activity的,在Activity销毁的时候它也就销毁了,不会再存在;但是,如果传入
this.getApplicationContext(),就表示它的生命周期是整个应用程序。关于Context的更多信息请看:http://blog.csdn.net/qinjuning/article/details/7310620
关于BaseAdapter
适配器,对NET开发的熟悉的童鞋对Adatper这个应该是非常了解的,在数据库访问的时候,往往是得到Adapter,然后调用Dataset的Fill方法将数据放到Dataset中,Android中也有很多的Adapter,这个的汉语意思是
适配器,从我自己的角度去理解,我觉得这个应该叫做数据适配器,因为这个Adapter是带了一定的数据,并且负责将该数据按照一定的方式组织起来,也就是规定了数据的显示方式。
这里我想到了一个词语,数据模板,这也是WPF中提到的,数据模板就是定义了数据是如何显示的,BaseAdapter是所有Adatper的基类,通过重写里面的getView方法里面就对获取的数据进行设置,下面是程序中的一
个:
@Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
ViewHolder holder;
if (convertView==null) {
convertView=LayoutInflater.from(context).inflate(R.layout.group_item_view, null);
holder=new ViewHolder();
holder.groupItem=(TextView) convertView.findViewById(R.id.itemText);
convertView.setTag(holder);
}
else{
holder=(ViewHolder) convertView.getTag();
}
holder.groupItem.setTextColor(Color.BLACK);
holder.groupItem.setText(list.get(position));
return convertView;
}
static class ViewHolder {
TextView groupItem;
}
在这里我遇到了一个问题,就是我这个方法只循环了一次,也就是只显示list数组中的第一条数据,找了半天的原因,总算是雨过天晴,有种拨开云雾见太阳的感觉,原因是布局的,我在布局中添加了一个背景图片
,图片过大,导致只能显示第一条,此外我用的是线性布局,该布局的大小好像是根据里面所容纳的内容动态调整,当将背景图片去掉后,就没问题了。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/guide01"
android:orientation="vertical"
>
<TextView
android:id="@+id/itemText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="5dp"
android:paddingLeft="12dp"
android:paddingRight="5dp"
android:paddingTop="0dp" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
<TextView
android:id="@+id/itemText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="5dp"
android:paddingLeft="12dp"
android:paddingRight="5dp"
android:paddingTop="0dp" />
</LinearLayout>
跟多信息请看:http://biancheng.dnbcw.info/shouji/372542.html
关于布局和Code-behind
布局,就像入眼的美女,系统能否得到用户的任何,界面一看便知,先将功能放到一边,这是我最近悟出来的,也许跟我的工作有关,因为我一直是写功能的,很少关注界面。对于漂亮的界面,我也只能暗自赞叹,
觉得这是一件很不可思议的事情,温馨的界面,就如婀娜多姿的美女一样,岂能被人弃之眼外。代码是给开发人员看的,而界面是给所有人员看的,而布局文件正是如此。没有代码的界面就如水一样的平静,躺在那
里移动不懂,代码让界面有了活力,似乎能听到画画的流水声。id 就是名字一样和人的身份证一样,通过id和布局文件取得联系,在后台进行操作,每一个id有其特定的寓意,不同的语言可能有所不一样,有的是id
有的是name等,id的获取是通过查询而来,就如findViewById,代码中得到了控件,就可以用代码给这个控件附加动力,让其有活力。
Android的布局是用xml文件来描述的,而逻辑操作则在Java文件中,看到后停留片刻,不禁问自己,这个世界到底发生了什么,好像在编程的世界中,现在都采用这种界面布局和代码分离的这种模式,也就是所谓的
code-behind。Flex,如此,WPF如此,Android亦如此。
其实这是一种合理的模式,一种可以将开发人员解脱出来的模式,界面有界面的人员,编码有编码的人员。其实不仅仅如此,如果不采用这些界面布局文件,用代码也是完全可以的。而有的时候,代码更能清楚一些
操作,以下这两种方式是完全等价的。
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXScale="1.0"
android:toXScale="0.0"
android:fromYScale="1.0"
android:toYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:duration="2000">
</scale>
mLitteAnimation = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
mLitteAnimation.setDuration(2000);
不知道这样的解释是否合理,我们所看到的界面其实是一种层次结构的显示,用xml这样的描述再好不过了。对于这些所谓的描述文件,也就是xml或者类似xml的,其元素名称往往对应代码中的对象对应,而属性则对
应对象的属性。布局文件是从结构上给我们直观的显示,其内部是如何实现的,这个是由编译器来完成的,对于喜欢追根问底的程序员来说,这种不能清楚的表达其代码之间的逻辑结构,代码可以更清楚的表述其实
现逻辑,在这中code-behind的方式中,代码就完完全全的可以关注逻辑功能了,下面是实现一个登陆界面的小功能。
package com.example.logincodeui;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.os.Bundle;
import android.text.InputFilter;
import android.text.method.PasswordTransformationMethod;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
public class MainActivity extends Activity implements OnClickListener {
private static final int BUTTON_ID_OK = 5000000;
private static final int BUTTON_ID_CANCEL = 6000000;
private static final int TEXT_ID_ONE = 111111;
private static final int TEXT_PASSWD = 222222;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TableLayout tableLayout = new TableLayout(this);
setContentView(tableLayout);
TableRow row1 = new TableRow(this);
tableLayout.addView(row1);
TextView view1 = new TextView(this);
view1.setText("账号名称:");
view1.setWidth(100);
EditText text1 = new EditText(this);
text1.setWidth(150);
text1.setSingleLine();
text1.setFilters(new InputFilter[] { new InputFilter.LengthFilter(15) });
text1.setId(TEXT_ID_ONE);
row1.addView(view1);
row1.addView(text1);
TableRow row2 = new TableRow(this);
tableLayout.addView(row2);
TextView view2 = new TextView(this);
view2.setWidth(100);
view2.setText("账号密码:");
EditText text2 = new EditText(this);
text2.setSingleLine();
text2.setWidth(150);
// 设置为密码模式
text2.setTransformationMethod(new PasswordTransformationMethod());
// 设置最大长度,为15
text2.setFilters(new InputFilter[] { new InputFilter.LengthFilter(15) });
text2.setId(TEXT_PASSWD);
row2.addView(view2);
row2.addView(text2);
TableRow row3 = new TableRow(this);
tableLayout.addView(row3);
Button b1 = new Button(this);
b1.setText("确定");
b1.setId(BUTTON_ID_OK);
b1.setOnClickListener(this);
Button b2 = new Button(this);
b2.setText("取消");
b2.setId(BUTTON_ID_CANCEL);
b2.setOnClickListener(this);
row3.addView(b1);
row3.addView(b2);
}
@Override
public void onClick(View v) {
EditText t1 = (EditText) findViewById(TEXT_ID_ONE);
EditText t2 = (EditText) findViewById(TEXT_PASSWD);
if (v.getId() == BUTTON_ID_OK) {
Builder alertDialog = new AlertDialog.Builder(this);
alertDialog.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface v, int btn) {
v.cancel();
}
});
alertDialog.setTitle("输入的信息:" + t1.getText() + " 密码:"
+ t2.getText());
alertDialog.show();
} else if (v.getId() == BUTTON_ID_CANCEL) {
t1.setText("");
t2.setText("");
}
}
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<TableLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="0dp"
android:layout_marginTop="0dp" >
<TableRow
android:id="@+id/tableRow1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:text="账号名称"
android:width="100dp" >
</TextView>
<EditText
android:id="@+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:minWidth="150dp" >
</EditText>
</TableRow>
<TableRow
android:id="@+id/tableRow2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="账号密码"
android:width="100dp" />
<EditText
android:id="@+id/editText2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textWebPassword"
android:minWidth="150dp" />
</TableRow>
<TableRow
android:id="@+id/tableRow3"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="确定"
android:textAlignment="center" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="取消" />
</TableRow>
</TableLayout>
</RelativeLayout>
工作很杂,所涉猎均为皮毛,正如同事所说的专一是一件很奢侈的事情!因为我不专一,博客中问题肯定很多,尽管我是一个追求完美的人,但是美中不足是我的结局,以上只是我的片面之言,欢迎交流。