Android学习笔记-第二章 UI控件

第二章 UI控件

一、视图组件View

View类:是Android所有UI组件的父类,它代表了屏幕上一块空白的矩形区域。

ViewGroup类:作为其它UI组件的容器使用,ViewGroup是View的子类。

应用界面的组成

Android 的所有UI组件都是建立在View、ViewGroup的基础之上。对于一个Android应用的图形用户界面来说,ViewGroup作为容器来盛装其他组件,ViewGroup里除了可以包含普通View组件之外,还可以再次包含ViewGroup组件。

视觉上的层次关系

mark

逻辑层次关系

mark

控制UI控件行为的方式

  1. 在xml布局文件中通过xml属性进行控制
  2. 在Java程序代码中通过调用set等方法控制

实际上不管使用哪种方式,它们控制用户界面行为的本质是完全一样的,大部分时候,控制UI组件的XML属性还有对应的方法。

View类是所有UI组件的基类,因经它包含的XML属性和方法是所有组件都可使用的

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、文本控件TextView

TextView : 直接继承自View,它的作用就是在界面上显示文本。

为什么SDK把它设计为EditText、Button两个UI控件的父类?

答:EditText、Button都可以界面上显示文本,不同的是EditText里的文本是可以给用户编辑的,而Button只是多了一个点击事件而已

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

match_parent 充满

wrap_content 正好

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:background="#00f">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:text="校园报修系统登录"
            android:textColor="#ffffff"
            android:textSize="30dp" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:background="@null"
            android:text="注册"
            android:textColor="#ffffff"
            android:textSize="30dp" />
    </RelativeLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="50dp"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="账号:"
                android:textSize="25dp"/>
            <EditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="请输入你的账号"/>
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="密码:"
                android:textSize="25dp"
                />
            <EditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:inputType="textPassword"
                android:hint="请输入密码"/>
        </LinearLayout>
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="登录"
            android:textSize="25dp"
            android:layout_marginTop="20dp"
            android:layout_marginRight="20dp"
            android:layout_marginLeft="20dp"/>


    </LinearLayout>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="43dp"
        android:text="齐鲁工业大学软件设计大赛"
        android:layout_gravity="right"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="by:Hello World!"
        android:layout_marginRight="43dp"
        android:layout_gravity="right"/>
</LinearLayout>

mark

三、图片控件ImageView

ImageView : 直接继承自View,它的作用就是在界面上显示图片。

实际上这个说法不太严谨,因为它能显示的不仅仅是图片,任何Drawable对象都可以使用ImageView来显示。
mark
mark
mark

语句举例

<ImageView
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:background="#f00"
        android:scaleType="centerCrop"
        android:src="@android:drawable/abc"/>

四、多选框控件CheckBox单选框控件RadioButton

CheckBox : 直接继承自Button,它的作用就是在界面提供一组选项,可以多选。

比如:我的喜欢的颜色: 红色 蓝色 绿色 紫色

RadioButton : 直接继承自Button,它的作用就是在界面提供一组选项,只能单选。

比如:性别: 男 女

实验记录

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".Order">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="选择你喜欢的颜色:"/>
        <CheckBox
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:checked="true"
            android:text="蓝色"/>
        <CheckBox
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="绿色"/>
        <CheckBox
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="黄色"/>
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <RadioGroup
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <RadioButton
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:checked="true"
                android:text=""/>
            <RadioButton
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text=""/>
        </RadioGroup>
    </LinearLayout>
</LinearLayout>

mark

五、拖动条控件SeekBar进度条控件ProgressBar日期、时间选择控件DatePicter、TimePicker

SeekBar:允许用户拖动滑块来改变值,因此拖动条通常用于对系统的某种数值进行调节,比如音量

Android:thumb指定一个Drawable对象,该对象将作为自定义滑块.

进度条控件ProgressBar

ProgressBar :通常用于向用户显示某个耗时操作完成的百分比。
mark
日期、时间选择控件DatePicter、TimePicker

DatePicker:供用户选择日期,从FrameLayout派生而来

TimePicker:供用户选择时间,也是从FrameLayout派生而来

可通过为DatePicker添加OnDateChangedListener进行监听,为TimePicker添加OnTimerChangedListener进行监听来实现。

Order.java

package me.cyning.uilesson2;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.DatePicker;
import android.widget.ProgressBar;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.TimePicker;

public class Order extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_order);
        SeekBar seekBar=findViewById(R.id.myseekbar);
        final TextView textView=findViewById(R.id.tv_seekbar);
        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                textView.setText(String.valueOf(progress-200));
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
        final ProgressBar progressBar=findViewById(R.id.progress);
        findViewById(R.id.add).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                progressBar.setProgress(progressBar.getProgress()+1);
            }
        });
        findViewById(R.id.dec).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                progressBar.setProgress(progressBar.getProgress()-1);
            }
        });
        DatePicker datePicker=findViewById(R.id.mydate);
        datePicker.getYear();
        datePicker.getMonth();
        datePicker.getDayOfMonth();
        TimePicker timePicker=findViewById(R.id.myTime);
        timePicker.getCurrentHour();
        timePicker.getCurrentMinute();
        //timePicker.getHour();//android6.0以上
    }
}

activity_order.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".Order">

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".Order">

        <SeekBar
            android:id="@+id/myseekbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:max="800"
            android:thumb="@mipmap/ic_launcher"/>
        <TextView
            android:id="@+id/tv_seekbar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="0"/>
        <ProgressBar
            android:id="@+id/progress"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:max="100"
            android:progress="50"
            style="?android:attr/progressBarStyleHorizontal"/>
        <Button
            android:id="@+id/add"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="增加"/>
        <Button
            android:id="@+id/dec"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="减少"/>
        <DatePicker
            android:id="@+id/mydate"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <TimePicker
            android:id="@+id/myTime"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
             />

    </LinearLayout>
</ScrollView>

mark
mark

六、列表选择控件Spinner

作用

弹出一个列表选择框,供用户选择。
继承自ViewGroup,因为它可以容纳很多列表项,
因此它也是一个容器控件

mark

第一种创建方式

使用数组资源设置下拉列表的列表项目

actvity_ui5.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".UI5">
    <Spinner
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:entries="@array/grade">
    </Spinner>
</RelativeLayout>

在res/value下新建arrays.xml文件
mark
arrays.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="grade">
        <item>小学二年级</item>
        <item>小学一年级</item>
        <item>小学三年级</item>
        <item>小学四年级</item>
<item>小学五年级</item>
    </string-array>
    </resources>

第二种创建方式

使用ArrayAdapter适配器创建

public ArrayAdapter(Context context, @LayoutRes int resource, @IdRes int textViewResourceId, @NonNull T[] objects)

context:当前所在Activity

resource:每一项的布局结构

textViewResourceId:包含textview

cobjects:每一项显示内容

activity_ui5.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".UI5">
    <Spinner
        android:id="@+id/my_spinner"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >
    </Spinner>
</RelativeLayout>

UI5.java

package me.cyning.uilesson2;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.Spinner;

public class UI5 extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ui5);
        Spinner spinner=findViewById(R.id.my_spinner);
        ArrayAdapter<String> adapter=new ArrayAdapter<String>(this,android.R.layout.simple_spinner_dropdown_item,android.R.id.text1,new String[]{"小学一年级","小学二年级","小学三年级"});
        spinner.setAdapter(adapter);
    }
}

七、列表控件ListView

ListView :列表控件,以垂直的形式显示所有的列表项。
mark

        android:divider="#f00" 设置分割行的颜色
        android:dividerHeight="10dp" 设置分隔符的宽度
        android:scrollbars="none" 是否显示滚动条
        android:overScrollMode="never" 是否显示系统默认滚到头的UI效果

第一种创建方法

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <ListView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:entries="@array/grade"/>
</RelativeLayout>

array.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="grade">
        <item>大学一年级</item>
        <item>大学二年级</item>
        <item>大学三年级</item>
        <item>中学一年级</item>
    </string-array>
</resources>

第二种创建方法-ArrayAdapter数组适配器

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <ListView
        android:id="@+id/demo_list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</RelativeLayout>

MainActivity.java

package me.cyning.ui6;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class MainActivity extends AppCompatActivity {
    String[] strings={
            "小学一年级","小学一年级","小学一年级","小学一年级","小学一年级","小学一年级","小学一年级","小学一年级","小学一年级","小学一年级","小学一年级","小学一年级","小学一年级","小学一年级","小学一年级",
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ListView listView=findViewById(R.id.demo_list_view);
        ArrayAdapter<String> adapter=new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1,android.R.id.text1,strings);
        listView.setAdapter(adapter);
    }
}

mark

第三种方法-SimpleAdapter简单适配器

构造方法:SimpleAdapter(Context context, List<? extends Map

context:上下文
data:数据源,是一个map对象列表
resource:每一项的布局资源id
from:在map对象中存储的key
to: 每一项布局资源中的需要显示文本的TextView的id数组

优点使用简单、方便

缺点只适合用于列表每一项中只需要动态加载文本的ListView

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <ListView
        android:id="@+id/demo_list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
</RelativeLayout>

item_user.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"/>
    <TextView
        android:id="@+id/tv_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
    android:id="@+id/tv_sex"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/tv_age"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

MainActivity.java

package me.cyning.ui6;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ListView listView=findViewById(R.id.demo_list_view);
        List<Map<String,?>> datalist=new ArrayList<>();
        for(int i=0;i<50;i++){
            Map<String,String> map=new HashMap<>();
            map.put("name","张三"+i);
            map.put("sex",i%2==0?"男":"女");
            map.put("age",10+i+"");
            datalist.add(map);
        }
        String[] from={"name","age","sex"};
        int[] to={R.id.tv_name,R.id.tv_age,R.id.tv_sex};
        SimpleAdapter adapter=new SimpleAdapter(this,datalist,R.layout.item_user,from,to);
        listView.setAdapter(adapter);

    }
}

mark

第四种方法-BaseAdapter适配器

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <ListView
        android:id="@+id/demo_list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
</RelativeLayout>

item_user.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <ImageView
        android:id="@+id/image_sex"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/tv_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
    android:id="@+id/tv_sex"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/tv_age"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

MainActivity.java

package me.cyning.ui6;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MainActivity extends AppCompatActivity {

    List<UserInfo> datalis;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        //初始化数据
        datalis=new ArrayList<>();
        for(int i=0;i<50;i++){
            UserInfo userInfo=new UserInfo();
            userInfo.age=10+i;
            userInfo.sex=i%2==0?"男":"女";
            userInfo.name="张三"+i;
            datalis.add(userInfo);
        }

        //为ListView设置适配器
        ListView listView=findViewById(R.id.demo_list_view);
        UserInfoListAdapter userInfoListAdapter=new UserInfoListAdapter();
        listView.setAdapter(userInfoListAdapter);


    }


    //写一个继承BaseAdapter的类
    class UserInfoListAdapter extends BaseAdapter{

        @Override
        public int getCount() {
            return datalis.size();
        }

        @Override
        public Object getItem(int position) {
            return datalis.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View itemRootView= LayoutInflater.from(parent.getContext()).inflate(R.layout.item_user,null);
            TextView tvName=itemRootView.findViewById(R.id.tv_name);
            tvName.setText(datalis.get(position).name);
            TextView tvAge=itemRootView.findViewById(R.id.tv_age);
            tvAge.setText(datalis.get(position).age+"");//默认数字代表资源ID
            TextView tvSex=itemRootView.findViewById(R.id.tv_sex);
            tvSex.setText(datalis.get(position).sex);
            ImageView imageView=itemRootView.findViewById(R.id.image_sex);
            if(datalis.get(position).sex.equals("男"))
                imageView.setBackgroundResource(R.drawable.male);
            if(datalis.get(position).sex.equals("女"))
                imageView.setBackgroundResource(R.drawable.femal);
            return itemRootView;
        }

    }
    //自定义内部类
    class UserInfo{
        String  name;
        int age;
        String sex;
    }


}

[mark

八、网络控件GridView

**GridView :**用于在界面上按行、列分布的方式来显示多个组件。
mark

用SimpleAdapter创建

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <GridView
        android:id="@+id/grid_view_menu"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:numColumns="3"/>
</RelativeLayout>

grid.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:gravity="center"><!-- 能让图标居中显示 -->

    <ImageView
        android:id="@+id/image_view"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:src="@mipmap/ic_launcher" />
    <TextView
        android:id="@+id/tv_menu"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="菜单" />

</LinearLayout>

MainActivity.java

package me.cyning.ui9;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.GridView;
import android.widget.SimpleAdapter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        //数据初始化
        List<Map<String,String>> dataList=new ArrayList<>();
        for(int i=0;i<12;i++){
            Map<String,String> map=new HashMap<>();
            map.put("menu_name","菜单"+i);
            dataList.add(map);
        }


        String[] from= {"menu_name"};
        int[] to={R.id.tv_menu};
        GridView gridView=findViewById(R.id.grid_view_menu);
        SimpleAdapter simpleAdapter=new SimpleAdapter(this,dataList,R.layout.grid,from,to);
        gridView.setAdapter(simpleAdapter);
    }
}

mark

用BaseAdapter创建

activity_main.xml和grid.xml与上一题相同

package me.cyning.ui9;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.SimpleAdapter;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MainActivity extends AppCompatActivity {
    List<MenuItem> datalist;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        GridView gridView=findViewById(R.id.grid_view_menu);


        datalist=new ArrayList<>();
        datalist.add(new MenuItem("菜单1",R.drawable.ec));
        datalist.add(new MenuItem("菜单2",R.drawable.mind));
        datalist.add(new MenuItem("菜单4",R.drawable.qq));
        datalist.add(new MenuItem("菜单5",R.drawable.sl));

        MenuAdapter menuAdapter=new MenuAdapter();
        gridView.setAdapter(menuAdapter);
    }
    class MenuAdapter extends BaseAdapter{

        @Override
        public int getCount() {
            return datalist.size();
        }

        @Override
        public Object getItem(int position) {
            return datalist.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View menu= LayoutInflater.from(parent.getContext()).inflate(R.layout.grid,null);
            TextView textView=menu.findViewById(R.id.tv_menu);
            textView.setText(datalist.get(position).menuName);
            ImageView imageView=menu.findViewById(R.id.image_view);
            imageView.setImageResource(datalist.get(position).menuDrawable);

            return menu;//不要忘记将你配置的View返回
        }
    }
    class MenuItem{
        String menuName;
        int menuDrawable;
        MenuItem(String menuName,int menuDrawable){
            this.menuDrawable=menuDrawable;
            this.menuName=menuName;
        }
    }


}

mark

九、ExpandableListView(可展开的ListView )

ExpandableListVivew是ListView的子类,它在普通ListView的基础上进行了扩展,它把应用中的列表项分为几组,每组里又可包含多个列表项。ExpandableListVivew的用法与普通ListView的用法非常相似,只是ExpandableListVivew显示的列表项应该由ExpandableAdapter提供

实现ExpandableAdapter的两种方式

  1. 使用SimpleExpandableListAdpater将两个List集合包装成ExpandableAdapter
  2. 扩展BaseExpandableListAdpter实现ExpandableAdapter

mark

1.使用SimpleExpandableListAdapter实现

public SimpleExpandableListAdapter(Context context,List<? extends Map<String, ?>> groupData, int groupLayout,String[]groupFrom, int[] groupTo,List<? extends List<? extends Map<String, ?>>> childData, int childLayout,String[]childFrom, int[] childTo)
  • context 与SimpleExpandableListAdapter关联的ExpandableListView的上下文。
  • groupData 一个Maps列表(List)。集合中的每个字典项与可折叠列表中的每个组元素一致。字典项提供了组元素包含的所有数据,并包含所有在"groupFrom"中指定的记录。
  • groupLayout 显示组元素的资源文件。该资源文件定义了如何显示组元素。该布局文件必须至少包括groupTo中所定义的View。(即groupTo中的View id数组必须都在该布局文件中找到
  • groupFrom 一个键值列表。对应与组相关联的Map中的键值。
  • grouptTo 组View应当显示groupFrom参数中的所有列数据。这些数据应当都用TextView来显示。列表中的前N个View从前N个groupFrom参数获得列元素的数据。
  • childData 一个Map列表的列表。外部列表中的每个实体对应一个组(按照组的位置编号)。在内部列表的每个实体对应某个组的子元素(按照子元素的位置编号)。该Map对应了子元素的数据。(按照childFrom数组中的值编号)。该Map包含了每个子元素的数据,并且应当包括所有在childFrom中指定的实体。
  • childLayout 显示子元素的资源文件。该资源文件定义了如何显示子元素。布局文件至少应该包括所有在childTo中定义的View。(即childTo中的view id数组必须都在该布局文件中找到)
  • childFrom 定义显示子元素的列名。该列名与childData中的子元素属性(字典键值)对应。
  • childTo 子View应当显示childFrom参数中的所有列数据。这些数据应当都用TextView来显示。列表中的前N个View从前N个childFrom参数获得列元素的数据。

2.使用BaseExpandableListAdpter实现

class BaseAdapter extends BaseExpandableListAdapter{
        @Override
        public int getGroupCount() {
            return 0;
        }

        @Override
        public int getChildrenCount(int groupPosition) {
            return 0;
        }

        @Override
        public Object getGroup(int groupPosition) {
            return null;
        }

        @Override
        public Object getChild(int groupPosition, int childPosition) {
            return null;
        }

        @Override
        public long getGroupId(int groupPosition) {
            return 0;
        }

        @Override
        public long getChildId(int groupPosition, int childPosition) {
            return 0;
        }

        @Override
        public boolean hasStableIds() {
            return false;
        }

        @Override
        public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
            return null;
        }

        @Override
        public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
            return null;
        }

        @Override
        public boolean isChildSelectable(int groupPosition, int childPosition) {
            return false;
        }
    }

实验记录:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ExpandableListView
        android:id="@+id/listview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>

item_groud.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:orientation="vertical"
    android:layout_gravity="center_vertical">
    <TextView
        android:id="@+id/tv_groud"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

item_child.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:orientation="vertical"
    android:layout_gravity="center_vertical"
    android:paddingLeft="50dp"
    >
    <TextView
        android:id="@+id/tv_child"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

MainActivity.java

package me.cyning.ui10;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ExpandableListView;
import android.widget.SimpleExpandableListAdapter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MainActivity extends AppCompatActivity {
    String[] groupString={"腾讯","阿里","百度"};


    String[][] childString={
            {"QQ","微信","gfdsg"},
            {"百度搜索","外卖","gdsf"},
            {"淘宝","gdsf","dsfg"}
    };
    List<Map<String,?>> groudData=new ArrayList<>();//不要忘记初始化
    List<List<Map<String,?>>> childdata=new ArrayList<>();//不要忘记初始化
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ExpandableListView expandableListView=findViewById(R.id.listview);
        for(int i=0;i<groupString.length;i++){
            Map<String,String> map=new HashMap<>();
            map.put("groudname",groupString[i]);
            groudData.add(map);
            List<Map<String,?>> itemLis=new ArrayList<>();
            for(int j=0;j<childString[i].length;j++){
                Map<String,String> map1=new HashMap<>();
                map1.put("itemName",childString[i][j]);
                itemLis.add(map1);
            }
            childdata.add(itemLis);
        }
        SimpleExpandableListAdapter adapter=new SimpleExpandableListAdapter
                (this,groudData,R.layout.item_group,new String[]{"groudname"},new int[]{R.id.tv_groud},childdata,R.layout.item_child,
        new String[]{"itemName"} ,new int[]{R.id.tv_child});
        expandableListView.setAdapter(adapter);
    }
}

mark

缺看的视频

十、容器控件-LinearLayout

概念:盛放基础UI控件的容器,用来自动控制容器内部每个组件的位置、大小

gravity子元素布置方向
layout_gravity相对于父布局的布置方向

mark

mark

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:gravity="center"
    android:orientation="vertical">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="居中"/>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="居中"/>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="居中"/>
</LinearLayout>

十一、容器控件-相对布局RelativeLayout

概念:相对布局容器内的子组件的位置总是相对兄弟组件、或父容器来决定的,这种布局方式也被称为相对布局。

mark

以下属性只能设置在子组件中

mark

mark

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <Button
        android:id="@+id/btn_lonin"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="菜单"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="音量+"
        android:layout_above="@+id/btn_lonin"
        android:layout_centerHorizontal="true"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="音量-"
        android:layout_below="@+id/btn_lonin"
        android:layout_centerHorizontal="true"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="频道+"
        android:layout_toLeftOf="@+id/btn_lonin"
        android:layout_centerVertical="true"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="频道-"
        android:layout_toRightOf="@+id/btn_lonin"
        android:layout_centerVertical="true"/>
</RelativeLayout>

mark

十二、帧布局FrameLayout

概念:帧布局给每个加入其中的组件创建一个空白的区域(称为一帧),每个子组件占据一帧。

mark

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <ImageView
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:background="#e0f0"/>
    <ImageView
        android:layout_width="160dp"
        android:layout_height="160dp"
        android:layout_margin="20dp"
        android:background="#0a0"/>
    <ImageView
        android:layout_width="120dp"
        android:layout_height="120dp"
        android:layout_margin="40dp"
        android:background="#080"/>
    <ImageView
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:layout_margin="60dp"
        android:background="#050"/>
     <!--先出现的控件新绘制在上面,后出现绘制在先绘制的上面-->
</FrameLayout>

mark

十三、绝对布局AbsoluteLayout

概念:由开发人员通过X、Y坐标来控制控件的显示位置

<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_x="104dp"
        android:layout_y="63dp"
        android:text="码子" />
</AbsoluteLayout>

十四、表格布局TableLayout

概念:表格布局模型以行列的形式管理子控件,每一行为一个TableRow的对象,当然也可以是一个View的对象。TableRow可以添加子控件,每添加一个为一列。

TableLayout属性

**android:collapseColumns:**将TableLayout里面指定的列隐藏,若有多列需要隐藏,请用逗号将需要隐藏的列序号隔开。
**android:stretchColumns:**设置指定的列为可伸展的列,以填满剩下的多余空白空间,若有多列需要设置为可伸展,请用逗号将需要伸展的列序号隔开。

**android:shrinkColumns:**设置指定的列为可收缩的列。当可收缩的列太宽(内容过多)不会被挤出屏幕。当需要设置多列为可收缩时,将列序号用逗号隔开。

<?xml version="1.0" encoding="utf-8"?>
<TableLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:stretchColumns="1,2"
    android:shrinkColumns="1">

    <TableRow
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="安卓"/>
        <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="安卓543534534534535353523563555543634253452345"/>
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="安卓3"/>
    </TableRow>
    <TableRow
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <EditText
            android:layout_width="100dp"
            android:layout_height="wrap_content"/>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="match_parent"/>

    </TableRow>
    <Button
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:text="单独一行"/>

</TableLayout>

mark

十五、ViewPager翻页控件

概念:ViewPager是android扩展包v4包中的类,这个类可以让用户左右切换当前的view

作用:安装后的第一次运行的新特性引导页

activity_main.java

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <android.support.v4.view.ViewPager
        android:id="@+id/my_view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </android.support.v4.view.ViewPager>

</RelativeLayout>

item_view_pager.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:id="@+id/item_image_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@mipmap/ic_launcher"/>设置背景为启动图标

</LinearLayout>

MainActivity.java

package me.cyning.ui16;

import android.graphics.Color;
import android.support.annotation.NonNull;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    List<View> viewList=new ArrayList<>();    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ViewPager viewPager=findViewById(R.id.my_view_pager);
        {
            View view = LayoutInflater.from(this).inflate(R.layout.item_view_pager, null);
            ImageView imageView=view.findViewById(R.id.item_image_view);
            imageView.setImageResource(R.drawable.wrre);//设置第一页的图片
            viewList.add(view);
        }
        {
            View view = LayoutInflater.from(this).inflate(R.layout.item_view_pager, null);
            ImageView imageView=view.findViewById(R.id.item_image_view);
            imageView.setImageResource(R.drawable.wrre);
            viewList.add(view);
        }
        {
            View view = LayoutInflater.from(this).inflate(R.layout.item_view_pager, null);
            ImageView imageView=view.findViewById(R.id.item_image_view);
            imageView.setImageResource(R.drawable.wrre);
            viewList.add(view);
        }
        viewPager.setAdapter(new PagerAdapter() {
            @Override
            public int getCount() {
                return viewList.size();
            }

            @Override
            public boolean isViewFromObject(@NonNull View view, @NonNull Object o) {
                return view==o;
            }

            @NonNull
            @Override
            public Object instantiateItem(@NonNull ViewGroup container, int position) {
                container.addView(viewList.get(position));
                return viewList.get(position);
            }

            @Override
            public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
                container.removeView(viewList.get(position));

            }
        });
    }
}

mark

十六、Menu菜单

概念:当我们按下Menu的硬件按钮时,Option Menu将被触发显示。
Menu有两种形式,Option menu和Context menu。 Option menu是按下设备的Menu硬件按钮弹出

MainActivity.java

package me.cyning.ui17;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;

import java.lang.reflect.Method;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        //1.第一种方法
        new MenuInflater(this).inflate(R.menu.main_menu,menu);
        //2.第二种方法
//        menu.add("菜单1");
//        menu.add("菜单2");
//        menu.add("菜单3");
//        menu.add("菜单4");
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case R.id.menu1:
                Toast.makeText(this,"用户点击了"+item.getTitle(),Toast.LENGTH_SHORT).show();
            break;
            case R.id.menu2:
                Toast.makeText(this,"用户点击了"+item.getTitle(),Toast.LENGTH_SHORT).show();
                break;
            case R.id.menu3:
                Toast.makeText(this,"用户点击了"+item.getTitle(),Toast.LENGTH_SHORT).show();
                break;
            case R.id.menu4:
                Toast.makeText(this,"用户点击了"+item.getTitle(),Toast.LENGTH_SHORT).show();
                break;
                default:break;
        }
        return super.onOptionsItemSelected(item);
    }

}

man_menu.xml(在menu文件夹下创建)

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/menu1"
        android:title="菜单一"/>
    <item android:id="@+id/menu2"
        android:title="菜单一"/>
    <item android:id="@+id/menu3"
        android:title="菜单一"/>
    <item android:id="@+id/menu4"
        android:title="菜单一"/>
</menu>

mark

十七、PopupWindow弹出框

概念: PopupWindow这个类用来实现一个弹出框,可以使用任意布局的View作为其内容,这个弹出框是悬浮在当前activity之上的。 PopupWindow的位置可以随意。

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btn_pow"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="弹出"/>
</RelativeLayout>

pop_windows.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="#bbbb">
    <TextView
        android:id="@+id/tv_tile"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/tv_mes"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <Button
            android:id="@+id/btn_can"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="取消"/>
        <Button
            android:id="@+id/btn_ok"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="确认"/>
    </LinearLayout>

</LinearLayout>

Main_activity.java

package me.cyning.ui18;

import android.graphics.drawable.BitmapDrawable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    PopupWindow popupWindow;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.btn_pow).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //让popupWindow默认显示
//                popupWindow.showAsDropDown(v);
                //让popupWindow显示在中间
                popupWindow.showAtLocation(MainActivity.this.getWindow().getDecorView(), Gravity.CENTER,0,0);
            }
        });



        //设计popupWindow的View
        View view= LayoutInflater.from(this).inflate(R.layout.pop_windows,null);
        ((TextView)view.findViewById(R.id.tv_tile)).setText("标题");
        ((TextView)view.findViewById(R.id.tv_mes)).setText("显示消息内容");
        view.findViewById(R.id.btn_can).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(v.getContext(),"你点击里取消",Toast.LENGTH_SHORT).show();
                popupWindow.dismiss();
            }
        });
        view.findViewById(R.id.btn_ok).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(v.getContext(),"你点击里确认",Toast.LENGTH_SHORT).show();
                popupWindow.dismiss();
            }
        });

        //设置popupWindow的View
        popupWindow=new PopupWindow(view, WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT);
        //弹出popupWindow后点外部,popupWindow消失
        popupWindow.setBackgroundDrawable(new BitmapDrawable());
        popupWindow.setFocusable(true);
    }
}

mark

十八、Fragment碎片(片段)

概念:fragment在应用的扮演的是模块化、可重用的角色。Fragment定义了自己的布局,以及通过它自己的生命周期回调方法定义了它自己的行为,你可以将fragment包含在多个activity中。
Activity和Fragment的关系:
Activity------ Fragment
房子 ------ 房间

1、fragment可以作为activity界面的一部分组成出现
2、一个activity中可以放置多个fragment,而且一个fragment也可以在多个activity中复用
3、可以在activity运行时动态的添加、删除、替换fragment
4、fragment有自己的生命周期,它的生命周期和所在activity的生命周期有一定的关联

onCreateView()方法

Fragment第一次绘制它的用户界面的时候,系统会调用此方法,为了绘制fragment的UI,此方法必须返回一个view,如果不显示UI,返回null即可。

加载方式

静态加载:在activity的xml文件中声明fragment,并且在fragment标签中通过name指定其实例化的fragment类。
动态加载:通过fragment事务来添加、删除、替换fragment。

静态加载

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <fragment
        android:id="@+id/maizifragent"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:name="me.cyning.ui19.MaiziFragment"/>

</RelativeLayout>

fragment_maizi.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="#f00">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="这是MaiziFragment的界面"/>

</LinearLayout>

MaiziFragment.java

package me.cyning.ui19;

import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class MaiziFragment extends Fragment {

    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view=inflater.inflate(R.layout.fragment_maizi,null);//此处第二个参数是null
        return view;
    }
}

MainActivity.java

package me.cyning.ui19;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}
动态加载

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">
    <Button
        android:id="@+id/btn_add"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="增加"/>
    <Button
        android:id="@+id/btn_delete"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="减少"/>
    <FrameLayout
        android:id="@+id/frame_layout"
        android:layout_width="match_parent"
        android:layout_height="200dp"/>

</LinearLayout>

fragment_maizi.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="#f00">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="这是MaiziFragment动态加载的界面"/>

</LinearLayout>

MaiziFragment.java

与静态加载相同

MainActivity.java

package me.cyning.ui19;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends FragmentActivity {
    MaiziFragment maiziFragment;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        maiziFragment=new MaiziFragment();

        findViewById(R.id.btn_add).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FragmentManager fm=getSupportFragmentManager();
                FragmentTransaction ft=fm.beginTransaction();
                ft.add(R.id.frame_layout,maiziFragment);
                ft.commit();
            }
        });
        findViewById(R.id.btn_delete).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FragmentManager fm=getSupportFragmentManager();
                FragmentTransaction ft=fm.beginTransaction();
                ft.remove(maiziFragment);
                ft.commit();
            }
        });

    }
}

mark

使用场景

mark

1、需要重用的界面(可以使用自定义view)
2、需要重用,但是包括多个View组合的界面(也可以使用自定义view)
3、需要重用,但是又和生命周期有关联的界面(只能使用fragment)

fragement_top.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:text="上面显示用户信息"/>

</LinearLayout>

TopFragment.java

package me.cyning.ui20;

import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class TopFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View rootView=inflater.inflate(R.layout.fragement_top,null);
        return rootView;
    }
}

fragment_bottom.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:layout_gravity="center">
    <Button
        android:id="@+id/btn_bottom"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="注销登录"
        />

</LinearLayout>

BottomFragment.java

package me.cyning.ui20;

import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class BottomFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View rootView=inflater.inflate(R.layout.fragment_bottom,null);

        rootView.findViewById(R.id.btn_bottom).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(getContext(),SecondActivity.class);
                startActivity(intent);
            }
        });



        return rootView;
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <FrameLayout
        android:id="@+id/fram_layout_top"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />
    <FrameLayout
        android:id="@+id/fram_layout_bottom"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />
实现两个组件界面平分
</LinearLayout>

MainActivity.java

package me.cyning.ui20;

import android.content.Intent;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        FragmentManager fm=getSupportFragmentManager();
        FragmentTransaction ft=fm.beginTransaction();
        ft.replace(R.id.fram_layout_top,new TopFragment());
        ft.replace(R.id.fram_layout_bottom,new BottomFragment());
        ft.commit();



    }
}

activity_second.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <FrameLayout
        android:id="@+id/fram_layout_top"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

SecondActivity.java

package me.cyning.ui20;

import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class SecondActivity extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);

        FragmentManager fm=getSupportFragmentManager();
        FragmentTransaction ft=fm.beginTransaction();
        ft.replace(R.id.fram_layout_top,new TopFragment());
        ft.commit();
    }
}

mark

点击注册登录之后

mark

第一个图中有两个平分布局的Fragment,点击下面的按钮后,第二个Activity是重新利用了上面的Fragment

图一实现一个Activity中实现多个Fragment

图二实现了一个Fragment在不同Activity中重复使用

Fragment与Activity通信

1、fragment直接调用getActivity(),activity直接调用fragment的方法
2、在Fragment中设置回调接口
3、通过handler通信
4、通过广播通信,系统广播、应用内广播

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">
    <Button
        android:id="@+id/btn_add"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="增加"/>
    <Button
        android:id="@+id/btn_delete"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="减少"/>
    <FrameLayout
        android:id="@+id/frame_layout"
        android:layout_width="match_parent"
        android:layout_height="200dp"/>
    <Button
        android:id="@+id/btn_motify"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="修改Fragment的几面"/>
    <TextView
        android:id="@+id/tv_in_activity"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

MainActivity.java

package me.cyning.ui19;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends FragmentActivity {
    MaiziFragment maiziFragment;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        maiziFragment=new MaiziFragment();
        maiziFragment.setOnBtnClickListener(new MaiziFragment.OnBtnClickListener() {
            @Override
            public void onBtnClick() {
                    TextView textView=findViewById(R.id.tv_in_activity);
                    textView.setText("回调的方式从Fragment修改activity");
            }
        });

        findViewById(R.id.btn_add).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FragmentManager fm=getSupportFragmentManager();
                FragmentTransaction ft=fm.beginTransaction();
                ft.add(R.id.frame_layout,maiziFragment);
                ft.commit();
            }
        });
        findViewById(R.id.btn_delete).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FragmentManager fm=getSupportFragmentManager();
                FragmentTransaction ft=fm.beginTransaction();
                ft.remove(maiziFragment);
                ft.commit();
            }
        });
        findViewById(R.id.btn_motify).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                    maiziFragment.modify();
            }
        });


    }
//   public  void modify(){
//      TextView textView=findViewById(R.id.tv_in_activity);
//      textView.setText("从Fragment修改activity");
//   }

}

fragment_maizi.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="#f00">
    <TextView
        android:id="@+id/tv_in_fragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="这是MaiziFragment动态加载的界面"/>
    <Button
        android:id="@+id/btn_in_fragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

MaiziFragment.java

package me.cyning.ui19;

import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class MaiziFragment extends Fragment {
    public void setOnBtnClickListener(OnBtnClickListener onBtnClickListener) {
        this.onBtnClickListener = onBtnClickListener;
    }

    private OnBtnClickListener onBtnClickListener;

    public interface OnBtnClickListener{
        void  onBtnClick();
    }


    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view=inflater.inflate(R.layout.fragment_maizi,null);
        view.findViewById(R.id.btn_in_fragment).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//                MainActivity mainActivity= (MainActivity) getActivity();
//                mainActivity.modify();
                if(onBtnClickListener!=null){
                    onBtnClickListener.onBtnClick();
                }
            }
        });
        return view;
    }
    public  void  modify(){
        TextView textView=getView().findViewById(R.id.tv_in_fragment);
        textView.setText("已经修改里面元素的值");
    }

}

mark

十九、SwipeRefreshLayout下拉刷新

SwipeRefreshLayout是v4包下的一个下拉刷新控件

注意SwipRefreshLayout只能包含一个直接子view

SwipeRefreshLayout是v4包下的一个下拉刷新控件

1、setOnRefreshListener(OnRefreshListener listener) 设置下拉监听,当用户下拉的时候会去执行回调
2、setColorSchemeColors(int… colors) 设置 进度条的颜色变化,最多可以设置4种颜色
3、setProgressViewOffset(boolean scale, int start, int end) 调整进度条距离屏幕顶部的距离
4、setRefreshing(boolean refreshing) 设置SwipeRefreshLayout当前是否处于刷新状态,一般是在请求数据的时候设置为true,在数据被加载到View中后,设置为false。

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/swipe_refresh"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
>
    <ListView
        android:id="@+id/my_list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>


</android.support.v4.widget.SwipeRefreshLayout>

MainActiviy.java

package me.cyning.ui21;

import android.graphics.Color;
import android.os.Handler;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    SwipeRefreshLayout swipeRefreshLayout;
    ListView listView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        swipeRefreshLayout=findViewById(R.id.swipe_refresh);
        listView=findViewById(R.id.my_list_view);

        final List<String> datalst=new ArrayList<>();
        for(int i=0;i<30;i++){
            datalst.add(i+"");
        }
        final ArrayAdapter<String> adapter=new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,android.R.id.text1,datalst);
        listView.setAdapter(adapter);


        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        swipeRefreshLayout.setRefreshing(false);
                        Toast.makeText(MainActivity.this,"加载完成",Toast.LENGTH_SHORT).show();
                        for(int i=0;i<20;i++){
                            datalst.add("新加数据"+i);
                        }
                        adapter.notifyDataSetChanged();
                    }
                }, 5000);
            }
        });
        swipeRefreshLayout.setColorSchemeColors(Color.RED,Color.GREEN,Color.CYAN);
        swipeRefreshLayout.setProgressViewOffset(false,50,100);
    }
}

mark

二十、DrawerLayout侧滑菜单控件

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <!--第一个子view会作为内容显示区-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="显示内容"/>
    </LinearLayout>
    <!--第二子View会作为侧滑菜单-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/white"
        android:layout_gravity="left">
        <ListView
            android:id="@+id/list_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

    </LinearLayout>
    <!--第二子View会作为侧滑菜单-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/white"
        android:layout_gravity="right"
        android:orientation="vertical">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content" 
            android:text="用户信息"/>
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="退出登录"/>

    </LinearLayout>


</android.support.v4.widget.DrawerLayout>

MainActivity.java

package me.cyning.ui22;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ListView listView=findViewById(R.id.list_view);
        ArrayAdapter<String> adapter=new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1
                ,new String[]{"菜单1","菜单2","菜单3","菜单4"});
        listView.setAdapter(adapter);
    }
}

mark

mark

二十一、RecyclerView循环复用控件

优点:提供了一种插拔式的体验,高度的解耦,异常的灵活。

用法:
1、通过布局管理器LayoutManager,控制其显示的方式
2、通过ItemDecoration控制Item间的间隔(可绘制)
3、通过ItemAnimator控制Item增删的动画

横向布局
如果想要一个横向的List只要设置LinearLayoutManager如下就行,注意要声明mLayoutManager的类型是LinearLayoutManager而不是父类LayoutManager:
mLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
Grid布局
如果想要一个Grid布局的列表,只要声明LayoutManager为GridLayoutManager即可:
mLayoutManager = new GridLayoutManager(context,columNum);
mRecyclerView.setLayoutManager(mLayoutManager);
注意,在Grid布局中也可以设置列表的Orientation属性,来实现横向和纵向的Grid布局。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值