LinearLayout:
**特点:
a):默认是水平的方向的排列,可以进行选择在<LinearLayout orientation="vertical"/>
设置为垂直的布局的方向!
b):其中垂直的方向布局,能够实现水平方向的排列的控制:
左对齐、右对齐、水平居中生效。
c): 其中的水平方向的布局:能够实现对垂直方向的控制:
置顶、底部、竖直居中生效。
* 设置右对齐
android:layout_gravity="right"
**注意点:
如何进行控制水平方向的多个组件的等宽的设置。这个就需要对在一个父容器中的多个组件
上进行等分长度;
如果父类的组件的设置为vertical,那么layout_height=0(layout_weight=1)
如果父类的组件的设置为horionzal,那么layout_width=0(layout_weight=1)
RelativeLayout:相对的布局
a):在相对的布局中主要就进行避免覆盖的问题,就是组件1可能会覆盖在组件2上;
b):在相对的布局中在线性的orientation方向和权重在相对的布局中并不适用;
c):组件默认左对齐、顶部对齐
* 设置组件在指定组件的右边
android:layout_toRightOf="@id/tv1"
* 设置在指定组件的下边
android:layout_below="@id/tv1"
* 设置右对齐父元素
android:layout_alignParentRight="true"
* 设置与指定组件右对齐
android:layout_alignRight="@id/tv1"
需求:
设置简单的9方格:
android:text="中间" android:layout_centerInParent="true" android:text="上边" android:layout_above="@id/center" android:layout_alignRight="@id/center" android:layout_alignLeft="@id/center" android:text="下边" android:layout_below="@id/center" android:layout_alignRight="@id/center" android:layout_alignLeft="@id/center" android:text="左边" android:layout_toLeftOf="@id/center" android:layout_alignTop="@id/center" android:layout_alignBottom="@id/center" android:layout_alignParentLeft="true" android:text="左上" android:layout_toLeftOf="@id/center" android:layout_above="@id/center" android:layout_alignParentLeft="true"
FrameLayout:帧布局
* 组件默认位置都是左上角,组件之间可以重叠
* 可以设置上下左右对齐,水平竖直居中,设置方式与线性布局一样
* 默认组件都是左对齐和顶部对齐,每个组件相当于一个div
* 可以更改对齐方式
android:layout_gravity="bottom"
* 不能相对于其他组件布局
TableLayout:表格布局
**注意的地方:
a)
有几行,就有几个<TableRow/>
有几列,那么在<TableRow>中就有几个<TestView>
b)
根节点中可以设置以下属性,表示让第1列拉伸填满屏幕宽度的剩余空间
android:stretchColumns="1",weight设置也没有
c)
分割线:设置Textview设置行高"1dp"以及宽度为"match_parent"
<TextView android:layout_height="1dp" android:background="#000000" /> <TableRow > <TextView android:text="X" /> <TextView android:layout_span="2" android:text="Import" /> </TableRow>
d)
在首列中不能够放弃首列,那么在这一行的其次列中设置"layout_column='1'",他就变成了首列了
"layout_span=2"当前列占用俩列
**特点:
tableRow:表示一行,其该节点的每一个子节点表示“一列”
TableLayout的一级子节点还匹配父元素(宽度匹配、但是高度不匹配)。
TableRow的子节点的宽和高是包裹内容。
简单控件注意的地方
ScrollView
ScrollView滚动视图是指当拥有很多内容,屏幕显示不完时,需要通过滚动跳来显示的视图。ScrollView只支持垂直滚动。
1、ScrollView和HorizontalScrollView是为控件或者布局添加滚动条
2、上述两个控件只能有一个孩子,但是它并不是传统意义上的容器,但是可以不跟布局,如LinearLayout写它里面,LinearLayout在写布局
3、上述两个控件可以互相嵌套
4、滚动条的位置现在的实验结果是:可以由layout_width和layout_height设定
5、ScrollView用于设置垂直滚动条,HorizontalScrollView用于设置水平滚动条:需要注意的是,有一个属性是 scrollbars 可以设置滚动条的方向:但是ScrollView设置成horizontal是和设置成none是效果同,HorizontalScrollView设置成vertical和none的效果同。
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/blur" android:scrollbars="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:layout_width="match_parent" android:layout_height="50dp" android:gravity="center" android:text="生活指南" android:textColor="#fff" android:textSize="25sp" /> <com.ly.weather.view.IndexView android:id="@+id/chuangyi" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout></ScrollView>
用代码设置textview
personList = new ArrayList<Person>(); //把数据库的数据查询出来 MyOpenHelper oh = new MyOpenHelper(this); SQLiteDatabase db = oh.getWritableDatabase(); Cursor cursor = db.query("person", null, null, null, null, null, null, null); while(cursor.moveToNext()){ String _id = cursor.getString(0); String name = cursor.getString(1); String salary = cursor.getString(2); String phone = cursor.getString(3); M Person p = new Person(_id, name, phone, salary); personList.add(p); } V ListView lv = (ListView) findViewById(R.id.lv);C lv.setAdapter(new MyAdapter());
三种adapter:
class MyAdapter extends BaseAdapter{ //系统调用,用来获知集合中有多少条元素 @Override public int getCount() { return personList.size(); } //由系统调用,获取一个View对象,作为ListView的条目 //position:本次getView方法调用所返回的View对象,在listView中是处于第几个条目,那么position的值就是多少 @Override public View getView(int position, View convertView, ViewGroup parent) { Person p = personList.get(position); View v = null; //判断条目是否有缓存 if(convertView == null){ //把布局文件填充成一个View对象 v = View.inflate(MainActivity.this, R.layout.item_listview, null); } else{ v = convertView; } //获取布局填充器对象// LayoutInflater inflater = LayoutInflater.from(MainActivity.this);// 使用布局填充器填充布局文件// View v2 = inflater.inflate(R.layout.item_listview, null); //这三种其实都是一回事// LayoutInflater inflater2 = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);// View v3 = inflater2.inflate(R.layout.item_listview, null); //通过资源id查找组件,注意调用的是View对象(条目布局)的findViewById TextView tv_name = (TextView) v.findViewById(R.id.tv_name); tv_name.setText(p.getName()); TextView tv_phone = (TextView) v.findViewById(R.id.tv_phone); tv_phone.setText(p.getPhone()); TextView tv_salary = (TextView) v.findViewById(R.id.tv_salary); tv_salary.setText(p.getSalary()); return v; }; @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return 0; } }
目前上面的这份代码还是可以继续优化的, 虽然现在已经不会再重复去加载布局,但是每次在getView()方法中还是会调用View的findViewById()方法来获取一次控件的实例。可以借助一个 ViewHolder来对这部分性能进行优化,
新增了一个内部类 ViewHolder,用于对控件的实例进行缓存。当 convertView为时候, 创建一个 ViewHolder对象, 并将控件的实例都存放在 ViewHolder里, 然后调用View的setTag()方法,将 ViewHolder对象存储在 View中。当 convertView不为空的时候则调view的 getTag()方法, 把 ViewHolder重新取出。 这样所有控件的实例都缓存在了 ViewHol,就没有必要每次都通过 findViewById()方法来获取控件实例了。
class ViewHolder { TextView tv_name; TextView tv_phone; TextView tv_salary ; }if (convertView == null) { ... viewHolder=new ViewHolder(); viewHolder.tv_name=(TextView) v.findViewById(R.id.tv_name); viewHolder.tv_phone=(TextView) v.findViewById(R.id.tv_phone); viewHolder.tv_salary=(TextView) v.findViewById(R.id.tv_salary); v.setTag(viewHolder); // 将ViewHolder存储在View中 } else { v = convertView; viewHolder = (ViewHolder) v.getTag(); // 重新获取ViewHolder } viewHolder.tv_name.setText(p.getName()); .... return v;
ArrayAdapter
它可以通过泛型来指定要适配的数据类型, 然后在构造函数中把要适配的数据传入即可。。 ArrayAdapter有多个构造函数的重载,根据实际情况选择最合适的一种。
ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, data);
android.R.layout.simple_list_item_1作为 ListView子项布局的 id,这是一个 Android内置的
局文件, 里面只有一个 TextView, 可用于简单地显示一段文本。 和下边一样,下边是自定义了一个布局文件
String[] objects = new String[]{"小志","小志的儿子","萌萌"}; ListView lv = (ListView) findViewById(R.id.lv); lv.setAdapter(new ArrayAdapter<String>(this, R.layout.item_listvie, R.id.tv_name, objects));
arrayadapter也是可以操作不同数据的∶
SimpleAdapter
//集合中每个元素都包含ListView条目需要的所有数据,该案例中每个条目需要一个字符串和一个整型,所以使用一个map来封装这两种数据 List<Map<String, Object>> data = new ArrayList<Map<String,Object>>(); Map<String, Object> map1 = new HashMap<String, Object>(); map1.put("photo", R.drawable.photo1); map1.put("name", "小志的儿子"); data.add(map1); Map<String, Object> map2 = new HashMap<String, Object>(); map2.put("photo", R.drawable.photo2); map2.put("name", "小志"); data.add(map2); Map<String, Object> map3 = new HashMap<String, Object>(); map3.put("photo", R.drawable.photo3); map3.put("name", "赵帅哥"); data.add(map3); lv.setAdapter(new SimpleAdapter(this, data, R.layout.item_listview, new String[]{"photo", "name"}, new int[]{R.id.iv_photo, R.id.tv_name})); }
ListView的点击事件
listView.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view,int position, long id) {Fruit fruit = fruitList.get(position);Toast.makeText(MainActivity.this, fruit.getName(),Toast.LENGTH_SHORT).show();}});
使用 setOnItemClickListener()方法来为 ListView注册了一个监听器,当用户点击了 ListView中的任何一个子项时就会回调 onItemClick()方法, 在这个方法中可以通过 position参数判断出用户点击的是哪一个子项,然后获取到相应的水果
public void handleMessage(android.os.Message msg) { // 将这个SimpleAdapter对象设置到ListActivity当中 switch (msg.what) { case 1: mp3Infos = (List<Mp3Info>) msg.obj; for (Mp3Info mp3Info : mp3Infos) { HashMap<String, String> map = new HashMap<String, String>(); map.put("mp3_name", mp3Info.getMp3Name()); map.put("mp3_size", mp3Info.getMp3Size()); list.add(map); simpleAdapter.notifyDataSetChanged(); Log.d("mp3Info", String.valueOf(list.size())); }
listview的排序:
实际上就是arraylist的排序,因为list的adapter是就是个集合,它排了序list列表也就排了序
public class Main { public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<Integer>(); list.add(2); list.add(1); list.add(8); list.add(3); list.add(5); list.add(4); System.out.println("排序前:" + list); Collections.sort(list, new Comparator<Integer>() { @Override public int compare(Integer lhs, Integer rhs) { if (lhs < rhs) { return 1; } else { return -1; } } }); System.out.println("排序后:" + list); }}
ProgressBar
public void onClick(View v) {switch (v.getId()) {case R.id.button:if (progressBar.getVisibility() == View.GONE) {progressBar.setVisibility(View.VISIBLE);} else {progressBar.setVisibility(View.GONE);}break;default:break;}
在按钮的点击事件中,通过 getVisibility()方法来判断 ProgressBar是否可见,如果可见就将 ProgressBar隐藏掉,如果不可见就将 ProgressBar显示出来。重新运行程序,然后不断地点击按钮,就会看到进度条会在显示与隐藏之间来回切换。
还可以给 ProgressBar指定不同的样式,默认是圆形进度条,通过 style属性可以将它指定成水平进度条
<ProgressBarandroid:id="@+id/progress_bar"android:layout_width="match_parent"android:layout_height="wrap_content"style="?android:attr/progressBarStyleHorizontal"android:max="100"/>
指定成水平进度条后,还可以通过 android:max属性给进度条设置一个最大值,然在代码中动态地更改进度条的进度。修改 MainActivity中的代码,如下所示:
public void onClick(View v) {switch (v.getId()) {case R.id.button://每点击一次按钮,就获取进度条的当前进度,然后在现有的进度上加 10作为更新的进度。int progress = progressBar.getProgress();progress = progress + 10;progressBar.setProgress(progress);break;default:break;}}
AlertDialog.Builder builder = new Builder(this); builder.setTitle("选择你的性别");
AlertDialog.Builder builder = new Builder(this); builder.setTitle("请选择你认为最帅的人");
ProgressDialog
ProgressDialog和 AlertDialog有点类似,都可以在界面上弹出一个对话框,都能够屏蔽掉其他控件的交互能力。不同的是,ProgressDialog会在对话框中显示一个进度条,一般是用于表示当前操作比较耗时,让用户耐心地等待。它的用法和 AlertDialog也比较相似
ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);progressDialog.setTitle("This is ProgressDialog");progressDialog.setMessage("Loading...");progressDialog.setCancelable(true);progressDialog.show();
注意如果在 setCancelable()中传入了 false,表示 ProgressDialog是不能通过 Back键取消掉的,这时就一定要在代码中做好控制,当数据加载完成后必须要调用 ProgressDialog的dismiss()方法来关闭对话框,否则 ProgressDialog将会一直存在。