《Android第一行代码》之UI

来源:互联网 发布:全职高手周边淘宝网 编辑:程序博客网 时间:2024/06/05 03:11

第三章 UI

一、常用控件

1、TextView:
2、Button:
3、EditText:
4、ImageView:
5、ProgressBar:
设置其进度

            progress=bar.getProgress();            progress+=10;            bar.setProgress(progress);            if(progress==100){                bar.setVisibility(View.GONE);            }

6、AlertDialog

AlertDialog.Builder dialog=new AlertDialog.Builder(MainActivity.this);            dialog.setTitle("确认删除");            dialog.setMessage("你确认删除么?");            dialog.setCancelable(false);            dialog.setPositiveButton("确认", new DialogInterface.OnClickListener() {                @Override                public void onClick(DialogInterface dialog, int which) {                    // TODO Auto-generated method stub                    Toast.makeText(MainActivity.this, "已经删除", Toast.LENGTH_SHORT).show();                }            });            dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() {                @Override                public void onClick(DialogInterface dialog, int which) {                    // TODO Auto-generated method stub                    Toast.makeText(MainActivity.this, "已经取消", Toast.LENGTH_SHORT).show();                }            });            dialog.show();

7、ProgressDialog
和AlertDialog类似,只是内容为一个进度条。
进度加载完成之后,必须使用dismiss()来关闭对话框。

二、基本布局

1、LinearLayout
android:gravity 指定文字在控件中的对齐方式
android:layout_gravity: 指定控件在布局中的对齐方式

android:layout_weight: 按比例分配控件大小

2、RelativeLayout

3、FrameLayout

4、TableLayout

android:layout_span=”2” 将两列合并为一列

在TableRow中无法指定控件的宽度,通过android:stretchColumns=”1”,指定将第二列拉伸到最大。

5、GridLayout

三、自定义控件

Android中,控件和布局的继承结构如下图:

1、添加自定义标题布局(无操作的)
自定义一个布局title.xml,然后在mainactivity布局中引入

当然,需要将系统自带标题栏屏蔽
requestWindowFeature(Window.FEATURE_NO_TITLE);

2、创建自定义控件
上面方法自定义的标题栏并不能响应操作,采用自定义控件方法来实现操作。
(1)首先,构建一个title.xml布局文件
(2)然后,构建一个自定义标题控件TitleLayout:
利用LayoutInflater动态加载布局文件title.xml。
public class TitleLayout extends LinearLayout{

public TitleLayout( Context context, AttributeSet attrs) {    super(context, attrs);    LayoutInflater.from(context).inflate(R.layout.title, this);    Button edit=(Button) findViewById(R.id.title_edit);    Button back=(Button) findViewById(R.id.title_back);    edit.setOnClickListener(new OnClickListener() {        @Override        public void onClick(View v) {            // TODO Auto-generated method stub            Toast.makeText(getContext(), "Edit", Toast.LENGTH_SHORT).show();        }    });    back.setOnClickListener(new OnClickListener() {        @Override        public void onClick(View v) {            // TODO Auto-generated method stub            Toast.makeText(getContext(), "Back", Toast.LENGTH_SHORT).show();        }    }); }

}

(3)如同加入其它的控件一样,将该自定义的控件添加到mainactivity.xml文件中

四、ListView

1、最简单的Adapter
要将数据放置在ListView中,都需要一个adapter转换。
一个最简单的adapter,就是把一个字符串数组放置在ListView中。
ArrayAdapter接收3个参数:context,ListView单个子项布局id和数据。

    listView=(ListView) findViewById(R.id.listView1);    ArrayAdapter<String> adapter=new ArrayAdapter<String>(MainActivity.this,             android.R.layout.simple_list_item_1, data);    listView.setAdapter(adapter);

2、定制ListView界面
只显示文字很单调,需要显示图片等,则需要构建自定义的布局。
(1)数据:Fruit类
首先准备需要适配的数据,数据包括文字、图片id,定义一个Fruit类存放这些数据。
(2)子项布局:fruit_layout.xml
之后,需要自定义ListView中单个子项的布局。本例中就是一个图片加上一个文字。
(3)自定义适配器:FruitAdapter.java
该适配器中,最重要的是getView()方法。该方法在每个子项滚动到屏幕内时被调用。
position是该子项的位置,利用getItem(position)可以获得当前的Fruit实例fruit;
然后,利用LayoutInflater可以加载布局为fruit_layout的布局view;
该布局view即为步骤(2)中自定义的布局,通过view.findViewById()可以获得ImageView和TextView。
最后,将fruit中的imageId和name传入ImageView和TextView。

public class FruitAdapter extends ArrayAdapter{

private int resourceId;public FruitAdapter(Context context, int resource, List<Fruit> objects) {    super(context, resource, objects);    resourceId=resource;}public View getView(int position, View convertView, ViewGroup parent) {    Fruit fruit=getItem(position);    View view=LayoutInflater.from(getContext()).inflate(R.layout.fruit_layout, null);    TextView fruit_name=(TextView) view.findViewById(R.id.fruit_name);    ImageView fruit_image=(ImageView) view.findViewById(R.id.fruit_image);    fruit_image.setImageResource(fruit.getImageId());    fruit_name.setText(fruit.getName());    return view;}

}

(4)使用
List fruits=new ArrayList();

FruitAdapter adapter=new FruitAdapter(MainActivity.this, R.layout.fruit_layout, fruits);

在fruits中添加数据。

3、提升ListView效率
getView()每次都将布局重新加载一遍,效率很低。处理方法为:
(1)convertView
convertView将之前加载好的布局进行缓存,以便之后重用。则可以不必每次都使用LayoutInflater重新加载布局,而直接加载缓存的布局。
if(convertView==null) view=LayoutInflater.from(getContext()).inflate(R.layout.fruit_layout, null);
else
view=convertView;

(2)ViewHolder
每次都使用findViewById获取控件,效率低下。
使用convertView将之前已经find的view也一起缓存。
View有setTag()和getTag()方法,分别进行数据写入和读取。

采用自定义的ViewHolder类,将多个参数一起管理,比如TextView/ImageView等。

public class FruitAdapter extends ArrayAdapter {

public FruitAdapter(Context context, int resource, List<Fruit> objects) {    super(context, resource, objects);    resourceId = resource;}private int resourceId;public View getView(int position, View convertView, ViewGroup parent) {    Fruit fruit = getItem(position);    View view;    ViewHolder viewHolder;    if (convertView == null) {        viewHolder = new ViewHolder();   //一定要记住实例化对象啊        view = LayoutInflater.from(getContext()).inflate(                R.layout.fruit_layout, null);        viewHolder.fruit_image = (ImageView) view                .findViewById(R.id.fruit_image);        viewHolder.fruit_name=(TextView) view.findViewById(R.id.fruit_name);        view.setTag(viewHolder);    } else {        view = convertView;        viewHolder = (ViewHolder) view.getTag();    }    viewHolder.fruit_image.setImageResource(fruit.getImageId());    viewHolder.fruit_name.setText(fruit.getName());    return view;}class ViewHolder {    ImageView fruit_image;    TextView fruit_name;}

}

4、ListView点击事件
注册setOnItemClickListener()事件:

    listView.setOnItemClickListener(new OnItemClickListener() {        public void onItemClick(AdapterView<?> parent, View view,                int position, long id) {            Fruit fruit=fruits.get(position);            Toast.makeText(MainActivity.this, fruit.getName(), Toast.LENGTH_SHORT).show();        }    });

五、单位和尺寸

px: 像素
pt:磅数,1pt=1/72inch

dp:密度无关像素
密度dpi:屏幕每inch包含的像素数。
获取当前屏幕密度值:
float xdpi=getResources().getDisplayMetrics().xdpi;
float ydpi=getResources().getDisplayMetrics().ydpi;

sp:可伸缩像素。

规定,在160dpi屏幕上,1dp=1px;在320dpi屏幕上,1dp=2px.

六、最佳实践——聊天界面

APP: ChatWe
新内容有:
当有新内容时,刷新ListView中的显示:adapter.notifyDataSetChanged();
将ListView定位到最后一行:listView.setSelection(messages.size());
指定ListView中分割线为透明:android:divider=”#0000”

0 0
原创粉丝点击