阅读 262

Android 知识库

一 、UI基础入门

1.线性布局(LinerLayout)

重要属性

android:orientation: verticle/horhorizontal 方向:垂直/水平
android:layout_weight 权重
android:layout_gravity 重力
复制代码

2.相对布局(RelativeLayout)

android:layout_centerInParent
android:layout_alignParentLeft
android:layout_alignParentRight
android:layout_alignParentTop
android:layout_alignParentBottom
android:layout_centerHorizontal
android:layout_centerVertical

1.在参照物的某边
android:layout_toLeftOf
android:layout_toRightOf
android:layout_above
android:layout_below
2.和参照物的某边线对齐
android:layout_alignTop
android:layout_alignBottom
android:layout_alignLeft
android:layout_alignRight
复制代码

3.帧布局(FrameLayout)

android:layout_gravity="center" 重力
android:foreground="@mipmap/ic_launcher" 前景
android:foregroundGravity="right|bottom" 前景重力
复制代码

4.表格布局(TableLayout)

如果直接往TableLayout中添加控件,那么该控件与屏幕等宽
如果想使多个控件在同一行,那么我们在这些控件外层包裹一对TableRow
并且在这种情况下,控件宽度与内容适配
android:stretchColumns="*" 设置可以伸展的列,直接传列的索引,如果有多列,以,作为分割,*表示全部
android:shrinkColumns 设置可以缩小的列
android:collapseColumns="1" 设置可隐藏的列
复制代码

5.网格布局(GridLayout)

android:rowCount(行数量)
android:columnCount(列数量)
android:layout_row(位于第几行)
android:layout_rowSpan(跨几行)
复制代码

6.约束布局(ConstraintLayout)

app:layout_constraint方位_to方位Of="?"
?  : 1. parent    2.引用其他控件id

当前控件的某个方位和另一个参照物的某个方位对齐
app:layout_constraintLeft_toLeftOf  相当于RelativeLayout的alignLeft属性
app:layout_constraintRight_toRightOf 相当于RelativeLayout的alignRight属性
app:layout_constraintTop_toTopOf    相当于RelativeLayout的alignTop属性
app:layout_constraintBottom_toBottomOf  相当于RelativeLayout的alignBottom属性
app:layout_constraintStart_toStartOf    同Left_toLeftOf
app:layout_constraintEnd_toEndOf    同Right_toRightOf

当前控件的A侧会在参照物的B侧
app:layout_constraintLeft_toRightOf    相当于RelativeLayout的toRightOf
app:layout_constraintRight_toLeftOf    相当于RelativeLayout的toLeftOf
app:layout_constraintTop_toBottomOf    相当于RelativeLayout的below
app:layout_constraintBottom_toTopOf    相当于RelativeLayout的above
app:layout_constraintStart_toEndOf     同Left_toRightOf
app:layout_constraintEnd_toStartOf      同Right_toLeftOf

app:layout_constraintVertical_bias="0.53"     垂直偏移量,0.5在正中间
app:layout_constraintHorizontal_bias="0.53"     水平偏移量,0.5在正中间
复制代码

7.UI基础控件

View

处理文本内容的View(TextView)

1.TextView的继承关系

image.png

- 对长文本惊醒显示处理
- 支持HTML代码
- 内容有样式、链接效果
复制代码

2.被点击的View(Button)

Button注册点击事件的方法
1. 自定义内部类
<Button
    android:id="@+id/btn1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="通过自定义内部类实现点击事件"/>
复制代码
//1.获取按钮
Button btn1 = findViewById(R.id.btn1);
//点击事件:被点击时被触发的事件
MyClickListener mcl = new MyClickListener();
//2.为按钮注册点击事件监听器
btn1.setOnClickListener(mcl);       
复制代码
class MyClickListener implements View.OnClickListener{
    @Override
    public void onClick(View view) {
        //在控制台输出一条语句
        Log.e("TAG","刚刚点击的按钮时注册了内部类监听器对象的按钮");
    }
}
复制代码
2. 匿名内部类
<Button
    android:id="@+id/btn2"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="通过匿名内部类实现点击事件"/>
复制代码
//匿名内部类适用于有唯一操作的按钮
Button btn2 = findViewById(R.id.btn2);
btn2.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        //在控制台输出
        Log.e("TAG","==========匿名内部类==========");
    }
});
复制代码
3. 当前Activity去实现事件接口
<Button
    android:id="@+id/btn3"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="通过当前Activity去实现点击事件接口"/>
复制代码
Button btn3 = findViewById(R.id.btn3);
btn3.setOnClickListener(this);

@Override
public void onClick(View view) {
    Log.e("TAG","用本类实现了OnClickListener");
}
复制代码
4. 在当前布局文件中添加点击事件属性
<Button
    android:id="@+id/btn4"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="在xml文件中绑定"
    android:onClick="myClick"/>

<Button
    android:id="@+id/btn5"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="在xml文件中绑定2"
    android:onClick="myClick"/>
复制代码
//参数:被点击的控件对象
public void myClick(View v){
    switch (v.getId()){
        case R.id.btn4:
            Log.e("TAG","btn4======");
            break;
        case R.id.btn5:
            Log.e("TAG","btn5======");
            break;

    }
}
复制代码

3.处理图片内容的View(ImageView)

用来显示和控制图像的控件,可以对它进行放大,缩小,旋转等操作。 常见属性有:

android:src
android:background
复制代码

4.接收用户信息输入的View(EditText)

android:inputType
android:hint
android:maxLength
复制代码

5.进度条类的View(ProgressBar)

进度条,默认情况下是圆形,没有刻度,这是一个不断旋转的动画效果。通过设置style,可以显示传统的水平带刻度进度条。

image.png

<!--
    进度条:默认样式是转圈。修改样式需设置风格
    style 设置风格progressBarStyleHorizontal(水平进度条)
    android:progress=""   设置进度
    android:max=""      设置最大值,默认100
    android:indeterminate="true"   设置进度条一直滚动
-->
<ProgressBar
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

<ProgressBar
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    style="?android:attr/progressBarStyleHorizontal"
    android:progress="30"
    android:max="200"/>

<ProgressBar
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    style="?android:attr/progressBarStyleHorizontal"
    android:indeterminate="true"/>

<ProgressBar
    android:id="@+id/progress"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    style="?android:attr/progressBarStyleHorizontal"/>
复制代码
final ProgressBar progressBar = findViewById(R.id.progress);
progressBar.setProgress(80);
//在Android中,4.0以后是不能直接在线程中操作控件的
//进度条是个特例
new Thread(){
    @Override
    public void run() {
        for(int i = 1 ; i <= 100 ; i++) {
            progressBar.setProgress(i);
            try {
                Thread.sleep(30);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}.start();
复制代码

通用属性

image.png

image.png

二 、UI常用组件

1.Activity入门

1.Activity之间的跳转

image.png

<TextView
    android:id="@+id/titleTextView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="TextView"/>

<Button
    android:id="@+id/button"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Button"/>
复制代码
// 通过findViewById将layout中的控件找出来,并转化成View
final TextView textView = findViewById(R.id.titleTextView);
// 打到button这个view
Button button = findViewById(R.id.button);

// 设置点击事件
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // 为textView动态设置文本
        textView.setText(getString(R.string.app_name));

        // 跳转到一个NewActivity
        Intent intent = new Intent(TestActivity.this, TestActivity.class);
        startActivity(intent);

    }
});
复制代码

2.Activity四种启动模式

//设置启动模式:android:launchMode="singleTop"
<activity android:name=".TestActivity"
          android:launchMode="singleTop"
    android:label="testActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>

        <category android:name="android.intent.category.LAUNCHER"/>
    </intent-filter>
</activity>
复制代码

1.standard

image.png

2.singleTop

image.png

3.singleTask

image.png

4.singleInstance

image.png

2.Android菜单创建和使用

1.Menu分类

1.选项菜单(OptionMenu)

选项菜单是一个应用的主要单项,用于放置对应用产生全局影响的操作,如搜索/设置。

image.png

1.通过XML资源来设计menu

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <!--showAsAction属性值:always :直接在标题栏显示
    never:不显示
    withText:控制图标和文本一起显示
    ifRoom:有空间就显示-->
    <item android:title="保存"
        android:id="@+id/save"
        android:icon="@mipmap/ic_launcher"
        app:showAsAction="always"/>
    <item android:title="设置"
        android:id="@+id/setting"/>
    <item android:title="更多操作" >
        <menu >
            <item android:title="退出"
                android:id="@+id/exit"/>
            <item android:title="子菜单2" />
            <item android:title="子菜单3" />
        </menu>
    </item>
</menu>
复制代码
public boolean onCreateOptionsMenu(Menu menu) {
    //加载菜单资源
    //通过XML资源来设计menu
    getMenuInflater().inflate(R.menu.option,menu);
    //一定要记得返回true,否则菜单不显示
    return true;
}
复制代码

2.纯java代码设计menu

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    //纯java代码设计menu
    /*
    设置
    更多
        添加
        删除
     */
    // Menu
    //参数1:组id     参数2:菜单项id    参数3:序号   参数4:设置
    menu.add(1, 1, 1,"设置");
    SubMenu sub = menu.addSubMenu(1,2,2,"更多");
    // SubMenu
    sub.add(2,3,1,"添加");
    sub.add(2,4,2,"删除");
    //一定要记得返回true,否则菜单不显示
    return true;
}
复制代码
//OptionMenu菜单项的选中方法
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()){
        case 1:
            Toast.makeText(this,"设置",Toast.LENGTH_SHORT).show();
            break;
        case 2:
            Toast.makeText(this,"更多",Toast.LENGTH_SHORT).show();
            break;
        case 3:
            Toast.makeText(this,"添加",Toast.LENGTH_SHORT).show();
            break;
        case 4:
            Toast.makeText(this,"删除",Toast.LENGTH_SHORT).show();
            break;
        default:
            super.onOptionsItemSelected(item);

    }
    return true;
}
复制代码

2.上下文菜单(ContextMenu)

长按某个item不放,就会在屏幕中间弹出ContextMenu。

image.png

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/delete"
        android:title="删除" />
    <item android:title="重命名" >
        <menu >
            <item
                android:id="@+id/opera1"
                android:title="操作1" />
            <item
                android:id="@+id/opera2"
                android:title="操作2" />
        </menu>
    </item>
</menu>
复制代码
//ctx_btn:演示ContextMenu
//1.注册
registerForContextMenu(findViewById(R.id.ctx_btn));
//2.创建 覆盖onCreateContextMenu
//3.菜单项的操作 覆盖onContextItemSelected

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
    getMenuInflater().inflate(R.menu.context,menu);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
    switch (item.getItemId()){
        case R.id.delete:
            Toast.makeText(this,"删除",Toast.LENGTH_SHORT).show();
            break;
        case R.id.opera1:
            Toast.makeText(this,"操作1",Toast.LENGTH_SHORT).show();
            break;
        case R.id.opera2:
            Toast.makeText(this,"操作2",Toast.LENGTH_SHORT).show();
            break;
    }
    return super.onContextItemSelected(item);
}
复制代码

如果要为按钮设置上下文操作模式:

//①实现ActionMode CallBack(注释上述代码)
//②在view的长按事件中去启动上下文操作模式
findViewById(R.id.ctx_btn).setOnLongClickListener(new View.OnLongClickListener() {
    @Override
    public boolean onLongClick(View view) {
        startActionMode(cb);
        return false;
    }
});

ActionMode.Callback cb = new ActionMode.Callback() {
    //创建,在启动上下文操作模式(startActionMode(Callback))时调用
    @Override
    public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
        Log.e("TAG","创建");
        getMenuInflater().inflate(R.menu.context,menu);
        return true;
    }

    //在创建方法后进行调用
    @Override
    public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
        Log.e("TAG","准备");
        return false;
    }

    @Override
    public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
        Log.e("TAG","点击");
        switch (menuItem.getItemId()){
            case R.id.delete:
                Toast.makeText(MainActivity.this,"删除",Toast.LENGTH_SHORT).show();
                break;
            case R.id.opera1:
                Toast.makeText(MainActivity.this,"操作1",Toast.LENGTH_SHORT).show();
                break;
            case R.id.opera2:
                Toast.makeText(MainActivity.this,"操作2",Toast.LENGTH_SHORT).show();
                break;
        }
        return true;
    }

    //上下文操作模式结束时被调用
    @Override
    public void onDestroyActionMode(ActionMode actionMode) {
        Log.e("TAG","结束");
    }
};
复制代码

3.弹出菜单(PopupMenu)

一个模态形式展示的弹出风格的菜单,绑在某个View上,一版出现在被绑定的View的下方。

image.png

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/copy"
        android:title="复制" />
    <item
        android:id="@+id/paste"
        android:title="粘贴" />
</menu>
复制代码
//popup_btn:演示PopupMenu
final Button popupBtn = findViewById(R.id.popup_btn);
popupBtn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        //①实例化PopupMenu对象 (参数2:被锚定的view)
        final PopupMenu menu = new PopupMenu(MainActivity.this,popupBtn);
        //②加载菜单资源:利用MenuInflater将Menu资源加载到PopupMenu.getMenu()所返回的Menu对象中
        //将R.menu.xx对于的菜单资源加载到弹出式菜单中
        menu.getMenuInflater().inflate(R.menu.popup,menu.getMenu());
        //③为PopupMenu设置点击监听器
        menu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem menuItem) {
                switch (menuItem.getItemId()){
                    case R.id.copy:
                        Toast.makeText(MainActivity.this,"复制",Toast.LENGTH_SHORT).show();
                        break;
                    case R.id.paste:
                        Toast.makeText(MainActivity.this,"粘贴",Toast.LENGTH_SHORT).show();
                        break;
                }
                return false;
            }
        });
        //④千万不要忘记这一步,显示PopupMenu
        menu.show();
    }
});
复制代码

2.XML定义Menu的优势

  • 清晰的菜单结构
  • 将菜单内容与应用的逻辑代码分离
  • 资源适配更容易

3.XML定义的Menu不显示

  • onCreateOptionsMenu()方法必须返回true
  • onOptionsItemSelected方法返回true
  • 调用父类的默认实现

3.Android对话框处理

1.AlertDialog

2.自定义Dialog

3.PopupWindow

4.Activity生命周期

1.Activity生命周期

image.png

image.png

public class MainActivity extends AppCompatActivity {

    //单个Activity的生命周期:
    //1.正常启动onCreate-->onStart-->onReusme , 正常退出onPause-->onStop-->onDestory,
    // 再次启动onCreate-->onStart-->onResume
    //2.已经处于前台的Activity,点击主页按钮离开当前Activity,OnPause-->onStop,
    // 回到Activity:onRestart-->onStart-->onResume
    //3.Activity不可操作onPause-->onStop(如:息屏,打开了其他Activity),而应用被强行杀死了,
    //再回到Activity,onCreate-->onStart-->onResume

    //多个Activity切换时
    //当启动另一个Activity时,当前Activity:onPause-->onStop,当点击返回按钮,
    //使另一个Activity退出时,当前Activity:onRestart-->onStart-->onResume

    //对话框存在时
    //1.普通对话框对生命周期没有任何影响
    //2.如果有个Activity伪装成对话框模式,那么当它启动时,之前的Activity:onPause
    //“对话框”消失后,回调onResume再次回到前台

    //创建
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.e("TAG","onCreate----创建");
    }

    //启动
    @Override
    protected void onStart() {
        super.onStart();
        Log.e("TAG","onStart----启动");
    }

    //恢复
    @Override
    protected void onResume() {
        super.onResume();
        Log.e("TAG","onResume----恢复");
    }

    //暂停
    @Override
    protected void onPause() {
        super.onPause();
        Log.e("TAG","onPause----暂停");
    }

    //停止
    @Override
    protected void onStop() {
        super.onStop();
        Log.e("TAG","onStop----停止");
    }

    //销毁
    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.e("TAG","onDestroy----销毁");
    }

    //重启
    @Override
    protected void onRestart() {
        super.onRestart();
        Log.e("TAG","onRestart----重启");
    }
}
复制代码

2.Activity启动方式

1.显式启动

<Button
    android:id="@+id/btn1"
    android:onClick="myclick"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="显式打开第二个界面"/>
复制代码
public void myclick(View view){
    switch (view.getId()){
        case R.id.btn1://启动第二个Ativity
            //意图
            //参数1:环境上下文,当前环境(this)。
            //参数2:待跳转的Activity的类对象
            Intent it = new Intent(this, Main2Activity.class);
            startActivity(it);//启动Activity
            break;
    }
}
复制代码

2.隐式启动

1.隐式启动系统Activity(打开浏览器)
<Button
    android:id="@+id/btn2"
    android:onClick="myclick"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="隐式启动系统Activity(打开浏览器)"/>
复制代码
public void myclick(View view){
    switch (view.getId()){
        case R.id.btn2://隐式启动系统Activity
            //参数1:字符串(某Activity的别名)
            //参数2:打开的路径,通过 协议 来具体的确定打开什么Activity
            Intent it2 = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.baidu.com")); //tel:13338889999
            startActivity(it2);
            break;
    }
}
复制代码
2.隐式启动普通Activity
<Button
    android:id="@+id/btn3"
    android:onClick="myclick"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="隐式启动普通Activity" />
复制代码
public void myclick(View view){
    switch (view.getId()){
        //隐式启动普通Activity 
        //abc为别名,需要在AndroidManifest.xml文件里面去添加
        case R.id.btn3:
            Intent it3 = new Intent("abc");
            startActivity(it3);
            break;
}
复制代码
<activity android:name=".Main2Activity">
    <intent-filter>
        <!--取别名-->
        <action android:name="abc"/>
        <!--分组-->
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>
复制代码

3.startActivityForResult

<Button
    android:id="@+id/btn4"
    android:onClick="myclick"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="带结果返回的方式启动Activity" />
复制代码
public void myclick(View view){
        switch (view.getId()){
            case R.id.btn4:
                Intent it4 = new Intent(this,Main2Activity.class);
                //参数:请求码
                startActivityForResult(it4,1000);
                break;
        }
    }
复制代码
//如果时通过startActivityForResult的方式启动了第二个Activity
//当第二个Activity处理结束后,再回到的当前Activity时,一定会自动回调onActivityResult
//在该方法中我们可以处理第二个Activity返回的结果(如:拍照后得到的照片,从图库中选取的图片)
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    //resultCode:  0 , RESULT_CANCEL  取消    -1,RESULT_OK 正确处理完后返回
    if(resultCode == RESULT_OK) {
        //requestCode:用来区分该结果是来自于哪个Activity
        if (requestCode == 1000) {
            Log.e("TAG", "自动进入了onActivityResult,requestCode=" + requestCode + ",resultCode=" + resultCode);
            Log.e("TAG","返回的数据是:" + data.getStringExtra("myMsg"));
        }
    }
}
复制代码
TextView txt = findViewById(R.id.txt);
txt.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Intent it = new Intent();   //此时的意图不作为跳转界面使用,而是用来传递数据
        it.putExtra("myMsg", "这是来自第二个界面的信息");
        //设置结果
        //参数1:结果码,在上一个界面的onActivityResult方法中通过resultCode获取
        //参数2:意图对象,主要作用:放数据,在上一个界面的onActivityResult方法中通过data获取
        setResult(RESULT_OK, it);
        finish();
    }
});
复制代码

3.Activity信息传递

1.传递普通数据

<Button
    android:id="@+id/btn5"
    android:onClick="myclick"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="显式打开第二个界面,并传递数据"/>
复制代码
public void myclick(View view){
    switch (view.getId()){
        case R.id.btn5://启动第二个Ativity
            //意图
            //参数1:环境上下文,当前环境(this)。
            //参数2:待跳转的Activity的类对象
            Intent it5 = new Intent(this,Main2Activity.class);
            it5.putExtra("msg1","这是数据1");
            it5.putExtra("msg2",100);
            break;
    }
}
复制代码
//如果要获取上一个界面传来的数据,那么首先要获取做启动的意图
Intent it = getIntent();
String msg1 = it.getStringExtra("msg1");
//参数1:数据的name,参数2:默认值
int msg2 = it.getIntExtra("msg2", 0);
TextView txt = findViewById(R.id.txt);
txt.setText(msg1+"    "+msg2);
复制代码

2.传递对象数据

<Button
    android:id="@+id/btn6"
    android:onClick="myclick"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="显式打开第二个界面,并传递数据"/>
复制代码
//序列化:
//1.想把内存中的对象保存到一个文件或数据库中时
//2.像利用套接字Socket在网络中传递对象
public class Student implements Serializable {
    private String name;
    private int age;
    private String gender;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public Student(String name, int age, String gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }
}
复制代码
public void myclick(View view){
    switch (view.getId()){
        case R.id.btn6://启动第二个Ativity
            //意图
            //参数1:环境上下文,当前环境(this)。
            //参数2:待跳转的Activity的类对象
            Intent it6 = new Intent(this,Main2Activity.class);
            //利用Intent传递对象
            Student s = new Student("张三",22,"男");
            it6.putExtra("stu",s);
            break;
    }
}
复制代码
//如果要获取上一个界面传来的数据,那么首先要获取做启动的意图
Intent it = getIntent();
//获取序列化对象
Student stu = (Student) it.getSerializableExtra("stu");
if (stu != null) {
    TextView txt = findViewById(R.id.txt);
    txt.setText(stu.getName() + "    " + stu.getAge() + "    " + stu.getGender());
}
复制代码

5.Fragment创建及使用

1.Fragment设置思想

为什么需要Fragment

image.png

2.Fragment VS Activity

  • Fragment是到Android3.0+以后
  • 一个Activity可以运行多个Fragment
  • Fragment不能脱离Activity而存在
  • Activity是屏幕的主体,而Fragment是Activity的一个组成元素

3.Fragment生命周期

image.png

public class Fragment1 extends Fragment {

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        Log.e("TAG","onAttach--Fragment与Activity关联");
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.e("TAG","onCreate--Fragment创建好了");
    }

    //Fragment创建视图
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Log.e("TAG","onCreateView--Fragment视图创建好了");
        return inflater.inflate(R.layout.fragment_fragment1, container, false);
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        Log.e("TAG","onActivityCreated--Activity已经创建好了");
    }

    @Override
    public void onStart() {
        super.onStart();
        Log.e("TAG","onStart--Fragment启动");
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.e("TAG","onResume--Fragment显示");
    }

    @Override
    public void onPause() {
        super.onPause();
        Log.e("TAG","onPause--Fragment暂停");
    }

    @Override
    public void onStop() {
        super.onStop();
        Log.e("TAG","onStop--Fragment停止");
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        Log.e("TAG","onDestroyView--Fragment视图销毁");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e("TAG","onDestroy--Fragment销毁");
    }

    @Override
    public void onDetach() {
        super.onDetach();
        Log.e("TAG","onDetach--与Activity解除关联");
    }
}
复制代码

4. 加载Fragment

1.静态加载:XML

//静态加载:通过android:name属性指定Fragment的路径
//需要新建一个名为Fragment1的Fragment
<fragment
    android:id="@+id/fragment1"
    android:layout_width="200dp"
    android:layout_height="200dp"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    android:name="com.example.fragmentdemo.Fragment1"/>
复制代码

2.动态加载

<FrameLayout
    android:id="@+id/container"
    android:layout_width="200dp"
    android:layout_height="200dp"
    android:layout_marginStart="8dp"
    android:layout_marginLeft="8dp"
    android:layout_marginTop="8dp"
    android:layout_marginEnd="8dp"
    android:layout_marginRight="8dp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/fragment1"></FrameLayout>
复制代码
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //FragmentManager   FragmentTransaction
    //1.获取Fragment管理器
    FragmentManager manager = getSupportFragmentManager();
    //2.获取Fragment事务(/开启事务)
    FragmentTransaction transaction = manager.beginTransaction();
    //3.动态添加Fragment
    //参数1:容器id
    //参数2:Fragment对象
    final Fragment f2 = new Fragment2(); //需要新建一个名为Fragment2的Fragment
    transaction.add(R.id.container,f2);
    //4.提交事务
    transaction.commit();
}
复制代码

5.Fragment传值

从以下案例来了解传值

activity_tab_fragment.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=".TabFragmentActivity"
    android:orientation="vertical">

    <!--加载Fragment的容器-->
    <FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"/>
    
    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#515151"/>

    <RadioGroup
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#fff"
        android:orientation="horizontal">
        <RadioButton
            android:id="@+id/rb_index"
            android:text="首页"
            android:drawableTop="@drawable/tab_menu_index"
            style="@style/tab_menu_item"/>

        <RadioButton
            android:id="@+id/rb_channel"
            android:text="分类"
            android:drawableTop="@drawable/tab_menu_channel"
            style="@style/tab_menu_item"/>

        <RadioButton
            android:id="@+id/rb_list"
            android:text="我的学习"
            android:drawableTop="@drawable/tab_menu_list"
            style="@style/tab_menu_item"/>

        <RadioButton
            android:id="@+id/rb_me"
            android:text="我"
            android:drawableTop="@drawable/tab_menu_me"
            style="@style/tab_menu_item"/>
    </RadioGroup>
</LinearLayout>
复制代码

tab_menu_bg.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true">
        <shape>
            <solid android:color="#FFC4C4C4"></solid>
        </shape>
    </item>
    <item>
        <shape>
            <solid android:color="@android:color/transparent"></solid>
        </shape>
    </item>
</selector>
复制代码

tab_menu_channel.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@mipmap/channel_selected" android:state_checked="true"></item>
    <item android:drawable="@mipmap/channel_normal"></item>
</selector>
复制代码

tab_menu_index.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@mipmap/index_selected" android:state_checked="true"></item>
    <item android:drawable="@mipmap/index_normal"></item>
</selector>
复制代码

tab_menu_list.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@mipmap/list_selected" android:state_checked="true"></item>
    <item android:drawable="@mipmap/list_normal"></item>
</selector>
复制代码

tab_menu_me.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@mipmap/me_selected" android:state_checked="true"></item>
    <item android:drawable="@mipmap/me_normal"></item>
</selector>
复制代码

tab_menu_text.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="#ffffff" android:state_checked="true"/>
    <item android:color="#515151"/>
</selector>
复制代码

TabFragmentActivity.java

package com.example.fragment;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;

import android.os.Bundle;
import android.util.Log;
import android.view.View;

public class TabFragmentActivity extends AppCompatActivity implements Fragment3.MyListener {

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

        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.add(R.id.container, new IndexFragment());
        transaction.commit();
    }

    public void myclick(View view){
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        switch(view.getId()){
            case R.id.rb_index:
                transaction.replace(R.id.container, new IndexFragment());
                break;
            case R.id.rb_channel:  //Activity向Fragment传值
                //setArguments
                //1.实例化Fragment
                Fragment f1 = new Fragment1();
                //2.实例化一个Bundle对象
                Bundle bundle = new Bundle();
                //3.存入数据到Bundle对象中
                bundle.putString("msg1", "这是由Activity发往Fragment的数据");
                //4.调用Fragment的setArguments方法,传入Bundle对象
                f1.setArguments(bundle);
                //5.添加/替换显示的Fragment
                transaction.replace(R.id.container, f1);
                break;
            case R.id.rb_list:
                transaction.replace(R.id.container, new Fragment2());
                break;
            case R.id.rb_me:
                transaction.replace(R.id.container, new Fragment3());
                break;
        }
        transaction.commit();
    }

    @Override
    public void sendMsg(String msg) {
        Log.e("TAG","Fragment传回的数据:"+msg);
    }
}
复制代码

你需要新建4个Fragment,分别为Fragment1,Fragment2,Fragment3,Fragment4

Fragment1接收值

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.fragment_1, container, false);

    Bundle bundle = getArguments();
    String msg1 = bundle.getString("msg1");
    ((TextView)v.findViewById(R.id.txt1)).setText(msg1);

    return v;
}
复制代码

Fragment3向Activity传值

package com.example.fragment;

import android.content.Context;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class Fragment3 extends Fragment {
    private String value;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    //Fragment像Activity传值(接口回调)
    //1.定义一个接口,在该接口中声明一个用于传递数据的方法
    //2.让Activity实现该接口,然后重写回调方法,获取传入的值,然后做处理
    //3.在自定义Fragment中,声明一个回调接口的引用
    //4.在onAttach方法中,为第三步的引用赋值
    //5.在引用调用传递数据的方法
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_3, container, false);
    }

    private MyListener m1;

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        m1 = (MyListener) getActivity();
        m1.sendMsg("消息");
    }

    public interface MyListener {
        void sendMsg(String msg);
    }
}
复制代码

Activity接收值

@Override
public void sendMsg(String msg) {
    Log.e("TAG","Fragment传回的数据:" + msg);
}
复制代码

6.ListView

1.适配器

1.ArrayAdapter

//activity_array.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".ArrayActivity">

    <ListView
        android:id="@+id/list_view1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>
复制代码
//ArrayActivity.java

//1.准备布局(每一项的显示效果)
//2.准备数据源
//3.实例化适配器(布局+数据源)
//4.为ListView设置适配器
public class ArrayActivity extends AppCompatActivity {

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

        ListView listView1 = findViewById(R.id.list_view1);

        String[] data = {"AA","BB","CC","DD","EE","FF","GG","AA","BB","CC","DD","EE","FF","GG","AA","BB","CC","DD","EE","FF","GG","AA","BB","CC","DD","EE","FF","GG"};
        //参数1:环境上下文(this)
        //参数2:代表数据项所应用的布局
        //参数3:数据源(数组)

        //1.R.layout.item是自己写的只有文本的布局
        //ArrayAdapter adapter = new ArrayAdapter(this, R.layout.item, data);

        //2.android.R.layout.simple_list_item_1是android自带的只有文本的布局
        //ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, data);

        //3.当布局含有图片和文本的时候,可以用id指定文本
        ArrayAdapter adapter = new ArrayAdapter(this, R.layout.item2, R.id.txt1, data);
        listView1.setAdapter(adapter);
    }
}
复制代码
//item.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textSize="28sp"
    android:textColor="#ff0000"/>

复制代码
//item2.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:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@mipmap/ic_launcher"/>
    <TextView
        android:id="@+id/txt1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>
复制代码

2.SimpleAdapter

//activity_simple.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=".SimpleActivity">
    <ListView
        android:id="@+id/list_view2"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>
复制代码
//SimpleActivity.java
public class SimpleActivity extends AppCompatActivity {
    private List<Map<String, Object>> data = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_simple);
        //1.获取ListView对象
        ListView listView2 = findViewById(R.id.list_view2);
        //2.实例化适配器对象
        //参数1:this
        //参数2:数据源
        initData();
        //参数3:每一项布局
        //参数4:数据来源的key数组
        String[] from = {"img", "name", "mood"};
        //参数5:数据去向的id数组
        int[] to = {R.id.qq_img, R.id.qq_name, R.id.qq_mood};
        //参数45对应索引上,from数组的元素代码数据源每个map的key,该key所替代的数据
        //会作为to数组对应索引上id所代表的控件的内容显示处理
        SimpleAdapter adapter = new SimpleAdapter(this, data, R.layout.item3, from, to);
        //3.为ListView设置适配器
        listView2.setAdapter(adapter);
        //4.点击事件
        listView2.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                //用Toast提示Name Mood
                Map<String, Object> map = data.get(i);
                String name = map.get("name").toString();
                String mood = map.get("mood").toString();
                Toast.makeText(SimpleActivity.this, name+"    "+mood, Toast.LENGTH_SHORT).show();
            }
        });
    }

    private void initData() {
        //左边:头像  右上:名字  右下:心情
        Map<String, Object> map1 = new HashMap<>();
        map1.put("img", R.mipmap.caocao);
        map1.put("name", "曹操");
        map1.put("mood", "宁教我负天下人,休教天下人负我");

        Map<String,Object> map2 = new HashMap<>();
        map2.put("img",R.mipmap.zhenji);
        map2.put("name","甄姬");
        map2.put("mood","飘摇兮若流风之回雪,仿佛兮若轻云之蔽月");

        Map<String,Object> map3 = new HashMap<>();
        map3.put("img",R.mipmap.simayi);
        map3.put("name","司马懿");
        map3.put("mood","无奈天命之子");

        Map<String,Object> map4 = new HashMap<>();
        map4.put("img",R.mipmap.guojia);
        map4.put("name","郭嘉");
        map4.put("mood","哦");

        Map<String,Object> map5 = new HashMap<>();
        map5.put("img",R.mipmap.caocao);
        map5.put("name","曹操");
        map5.put("mood","宁教我负天下人,休教天下人负我");

        Map<String,Object> map6 = new HashMap<>();
        map6.put("img",R.mipmap.zhenji);
        map6.put("name","甄姬");
        map6.put("mood","飘摇兮若流风之回雪,仿佛兮若轻云之蔽月");

        Map<String,Object> map7 = new HashMap<>();
        map7.put("img",R.mipmap.simayi);
        map7.put("name","司马懿");
        map7.put("mood","无奈天命之子");

        Map<String,Object> map8 = new HashMap<>();
        map8.put("img",R.mipmap.guojia);
        map8.put("name","郭嘉");
        map8.put("mood","哦");

        data.add(map1);
        data.add(map2);
        data.add(map3);
        data.add(map4);
        data.add(map5);
        data.add(map6);
        data.add(map7);
        data.add(map8);
    }
}
复制代码
//item3
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:id="@+id/qq_img"
        android:layout_width="50dp"
        android:layout_height="65dp"
        android:background="@mipmap/caocao"/>

    <TextView
        android:id="@+id/qq_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/qq_img"
        android:textSize="26sp"
        android:text="曹操"/>

    <TextView
        android:id="@+id/qq_mood"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/qq_img"
        android:layout_below="@id/qq_name"
        android:textColor="#00ffff"
        android:text="测试数据"/>
</RelativeLayout>
复制代码

3.BaseAdapter

//activity_base.xml
<?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=".BaseActivity">
    <ListView
        android:id="@+id/list_view3"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    
    <ImageView
        android:id="@+id/write"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:src="@mipmap/write"
        android:layout_gravity="right|bottom"
        android:layout_margin="40dp"/>
</FrameLayout>
复制代码
//BaseActivity.java
public class BaseActivity extends AppCompatActivity {
    private ListView listView3;
    private ImageView write;
    private List<Msg> list = new ArrayList<>();
    private int[] ps = {R.mipmap.profile1, R.mipmap.profile2, R.mipmap.profile3, R.mipmap.profile4, R.mipmap.profile5, R.mipmap.profile6, R.mipmap.profile7, R.mipmap.profile8};
    private BaseAdapter adapter;

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

        listView3 = findViewById(R.id.list_view3);
        write = findViewById(R.id.write);

        initData();

        //需要传的参数:数据源,环境
        adapter = new MyAdapter(list, this);

        //设置适配器
        listView3.setAdapter(adapter);

        write.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Msg m = new Msg(R.mipmap.profile9, "paradox", "这是动态新增的说说", false);
                list.add(m);
                //通知适配器更新数据
                adapter.notifyDataSetChanged();
                //设置listview自动显示最新数据
                listView3.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
            }
        });
    }

    private void initData() {
        for (int i = 1; i <= 8 ; i++) {
            Msg msg = new Msg(ps[i-1], "用户"+i, "今天天气好晴朗,处处好风光"+i, i%2==0?true:false);
            list.add(msg);
        }
    }
}
复制代码
//Msg.java
public class Msg {
    private int profile;
    private String nickname;
    private String content;
    private  boolean isLike;

    public int getProfile() {
        return profile;
    }

    public void setProfile(int profile) {
        this.profile = profile;
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public boolean isLike() {
        return isLike;
    }

    public void setLike(boolean like) {
        isLike = like;
    }

    public Msg(int profile, String nickname, String content, boolean isLike) {
        this.profile = profile;
        this.nickname = nickname;
        this.content = content;
        this.isLike = isLike;
    }
}
复制代码
//item4.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:id="@+id/profile"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:src="@mipmap/profile1"
        android:layout_margin="5dp"/>
    <TextView
        android:id="@+id/nickname"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:text="用户1"
        android:textSize="26sp"
        android:layout_toRightOf="@id/profile"
        android:layout_marginTop="5dp"/>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:text="2048-10-24"
        android:textSize="22sp"
        android:layout_toRightOf="@id/profile"
        android:layout_below="@id/nickname"/>
    <TextView
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="啊,多么有意义的日子啊!!"
        android:textSize="22sp"
        android:layout_below="@id/profile"/>
    <ImageView
        android:id="@+id/repost"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:src="@mipmap/repost"
        android:layout_below="@id/content"
        android:layout_alignParentRight="true"
        android:layout_marginRight="10dp"/>
    <ImageView
        android:id="@+id/comment"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:src="@mipmap/comment"
        android:layout_below="@id/content"
        android:layout_toLeftOf="@id/repost"
        android:layout_marginRight="10dp"/>
    <ImageView
        android:id="@+id/like"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:src="@mipmap/like"
        android:layout_below="@id/content"
        android:layout_toLeftOf="@id/comment"
        android:layout_marginRight="10dp"/>
</RelativeLayout>
复制代码
//MyAdapter.java
//根据准备好的数据源和子项布局完成ListView效果的一一设置
//做出一些细节处理
public class MyAdapter extends BaseAdapter {
    private List<Msg> list;
    private Context ctx;

    public MyAdapter(List<Msg> list, Context ctx) {
        this.list = list;
        this.ctx = ctx;
    }

    //获取数量(设置ListView的长度)
    @Override
    public int getCount() {
        return list.size();
    }

    //获取视图(设置ListView每一项的显示效果)-- 每个视图出现时都会执行
    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        view = LayoutInflater.from(ctx).inflate(R.layout.item4, null);

        Msg msg = list.get(i);

        //头像
        ImageView profile = view.findViewById(R.id.profile);
        profile.setImageResource(msg.getProfile());

        //昵称
        TextView nickname = view.findViewById(R.id.nickname);
        nickname.setText(msg.getNickname());

        //内容
        TextView content = view.findViewById(R.id.content);
        content.setText(msg.getContent());

        //是否点赞
        ImageView like = view.findViewById(R.id.like);
        if(msg.isLike()){
            like.setImageResource(R.mipmap.liked);
        }else {
            like.setImageResource(R.mipmap.like);
        }

        //评论
        ImageView comment = view.findViewById(R.id.comment);
        comment.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(ctx, "你点击了评论", Toast.LENGTH_SHORT).show();
            }
        });

        //转发
        ImageView repost = view.findViewById(R.id.repost);
        repost.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(ctx, "你点击了转发", Toast.LENGTH_SHORT).show();
            }
        });

        return view;
    }

    //============================================================酱油方法
    //获取子项
    @Override
    public Object getItem(int i) {
        return null;
    }

    //获取子项id
    @Override
    public long getItemId(int i) {
        return 0;
    }
}
复制代码

2.BaseAdapter案例优化

  • 优化1:利用进去RecycleBin中的View,减少读view的赋值
  • 优化2:通过ViewHolder避免每次getView的时候大幅度使用findViewById操作
//根据准备好的数据源和子项布局完成ListView效果的一一设置
//做出一些细节处理
public class MyAdapter extends BaseAdapter {
    private List<Msg> list;
    private Context ctx;

    public MyAdapter(List<Msg> list, Context ctx) {
        this.list = list;
        this.ctx = ctx;
    }

    //获取数量(设置ListView的长度)
    @Override
    public int getCount() {
        return list.size();
    }

    //获取视图(设置ListView每一项的显示效果)-- 每个视图出现时都会执行
    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        //完成对view的设置;
        //将布局资源转为view
        //参数1:你所要引用的布局资源
        //RecycleBin
        ViewHolder holder;
        if(view == null){
            Log.e("TAG", "======" + i);
            //优化1:利用进去RecycleBin中的View,减少读view的赋值
            view = LayoutInflater.from(ctx).inflate(R.layout.item4, null);
            holder = new ViewHolder();
            holder.profile = view.findViewById(R.id.profile);
            holder.nickname = view.findViewById(R.id.nickname);
            holder.content = view.findViewById(R.id.content);
            holder.like = view.findViewById(R.id.like);
            holder.comment = view.findViewById(R.id.comment);
            holder.repost = view.findViewById(R.id.repost);
            view.setTag(holder);
        }else {
            //通过getTag()取出ViewHolder对象,然后能够直接通过holder.控件的方式在外面直接操作控件
            //从而避免了大幅度使用findViewById操作
            //而事实上,getTag()本身操作效率高
            holder = (ViewHolder) view.getTag();
        }

        Msg msg = list.get(i);

        //头像
//        ImageView profile = view.findViewById(R.id.profile);
        holder.profile.setImageResource(msg.getProfile());

        //昵称
//        TextView nickname = view.findViewById(R.id.nickname);
        holder.nickname.setText(msg.getNickname());

        //内容
//        TextView content = view.findViewById(R.id.content);
        holder.content.setText(msg.getContent());

        //是否点赞
//        ImageView like = view.findViewById(R.id.like);
        if(msg.isLike()){
            holder.like.setImageResource(R.mipmap.liked);
        }else {
            holder.like.setImageResource(R.mipmap.like);
        }

        //评论
//        ImageView comment = view.findViewById(R.id.comment);
        holder.comment.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(ctx, "你点击了评论", Toast.LENGTH_SHORT).show();
            }
        });

        //转发
//        ImageView repost = view.findViewById(R.id.repost);
        holder.repost.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(ctx, "你点击了转发", Toast.LENGTH_SHORT).show();
            }
        });

        return view;
    }

    //============================================================酱油方法
    //获取子项
    @Override
    public Object getItem(int i) {
        return null;
    }

    //获取子项id
    @Override
    public long getItemId(int i) {
        return 0;
    }

    //1.自定义一个类,叫做ViewHolder
    //2.将需要保存的视图声明为公开的属性
    //3.什么时候保存?当view为null时,完成对ViewHolder的示例化工作,并未各个空间属性赋值
    //4.什么时候用?什么时候都要用(性能提升是在view补位null时体现,滚动ListView时体现)
    //5.怎么用?当view为null时,完成了ViewHolder及内部控件属性的初始化工作后,调用一句代码
    //view.setTag(holder)
    //当view不为null时,holder = view.getTag();
    static class ViewHolder {
        public ImageView profile,like,comment,repost;
        public TextView nickname, content;
    }
}
复制代码

三 、网络操作与通讯

四 、高级控件

五 、数据存储

六 、流行框架

七 、高级应用

八 、Android动画处理与自定义View

持续更新中...

文章分类
Android
文章标签