Android项目实战系列—基于博学谷(五)个人资料

image

由于这个模块内容较多,篇幅较长,请耐心阅读。


个人资料模块分为两个部分


一、个人资料

1、个人资料界面

(1)、创建个人资料界面

com.buxuegu.activity包中创建一个java类,命名为UserInfoActivity。在res/layout文件夹下创建一个布局文件,命名为activity_user_info

(2)、界面代码——activity_user_info.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white">
    <include layout="@layout/main_title_bar"/>
    <RelativeLayout
        android:id="@+id/rl_head"
        android:layout_width="fill_parent"
        android:layout_height="60dp"
        android:layout_marginLeft="15dp"
        android:layout_marginRight="15dp">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:text="头像"
            android:textColor="#000000"
            android:textSize="16sp" />
        <ImageView
            android:id="@+id/iv_head_icon"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:src="@drawable/default_icon"/>
    </RelativeLayout>
    <View
        android:layout_width="fill_parent"
        android:layout_height="1dp"
        android:background="#E4E4E4"/>
    <RelativeLayout
        android:id="@+id/rl_account"
        android:layout_width="fill_parent"
        android:layout_height="60dp"
        android:layout_marginLeft="15dp"
        android:layout_marginRight="15dp">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:text="用户名"
            android:textColor="#000000"
            android:textSize="16sp"/>
        <TextView
            android:id="@+id/tv_user_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="5dp"
            android:text="account"
            android:textColor="#a3a3a3"
            android:textSize="14sp"/>
    </RelativeLayout>
    <View
        android:layout_width="fill_parent"
        android:layout_height="1dp"
        android:background="#E4E4E4"/>
    <RelativeLayout
        android:id="@+id/rl_nickName"
        android:layout_width="fill_parent"
        android:layout_height="60dp"
        android:layout_marginLeft="15dp"
        android:layout_marginRight="15dp">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:text="昵称"
            android:textColor="#000000"
            android:textSize="16sp"/>
        <TextView
            android:id="@+id/tv_nickName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="5dp"
            android:singleLine="true"
            android:text="昵称"
            android:textColor="#a3a3a3"
            android:textSize="14sp"/>
    </RelativeLayout>
    <View
        android:layout_width="fill_parent"
        android:layout_height="1dp"
        android:background="#E4E4E4"/>
    <RelativeLayout
        android:id="@+id/rl_sex"
        android:layout_width="fill_parent"
        android:layout_height="60dp"
        android:layout_marginLeft="15dp"
        android:layout_marginRight="15dp">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:text="性别"
            android:textColor="#000000"
            android:textSize="16sp"/>
        <TextView
            android:id="@+id/tv_sex"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="5dp"
            android:text=""
            android:textColor="#a3a3a3"
            android:textSize="14sp"/>
    </RelativeLayout>
    <View
        android:layout_width="fill_parent"
        android:layout_height="1dp"
        android:background="#E4E4E4"/>
    <RelativeLayout
        android:id="@+id/rl_signature"
        android:layout_width="fill_parent"
        android:layout_height="60dp"
        android:layout_marginLeft="15dp"
        android:layout_marginRight="15dp">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:singleLine="true"
            android:text="签名"
            android:textColor="#000000"
            android:textSize="16sp"/>
        <TextView
            android:id="@+id/tv_signature"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="5dp"
            android:textColor="#a3a3a3"
            android:textSize="14sp"/>
    </RelativeLayout>
    <View
        android:layout_width="fill_parent"
        android:layout_height="1dp"
        android:background="#E4E4E4"/>
</LinearLayout>

2、创建UserBean

选中com.boxuegu包,新建一个bean包。在bean包中创建一个Java类,命名为UserBean。代码如下
package com.boxuegu.bean;

public class UserBean {
    public String userName;  //用户名
    public String nickName;  //昵称
    public String sex;       //性别
    public String signature; //签名
}

3、创建用户信息表

选中com.boxuegu包,新建一个sqlite包。在sqlite包中创建一个Java类,命名为QLiteHelper。因为SQLiteHelper类继承SQLiteOpenHelper类,需要修改主类。代码如下
package com.boxuegu.sqlite;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

//SQLiteHelper类继承自SQLiteOpenHelper类
public class SQLiteHelper extends SQLiteOpenHelper {

    public static final int DB_VERSION = 1;  //数据库的版本
    public static final String DB_NAME = "wordpress.db";   //数据库的名称
    public static final String U_USERINFO = "userinfo";   //个人资料
    public SQLiteHelper(Context context){
        super(context,DB_NAME,null,DB_VERSION);
    }
    
    //创建数据库
    @Override
    public void onCreate(SQLiteDatabase db){
        //创建用户信息表
        db.execSQL("CREATE TABLE IF NOT EXISTS " + U_USERINFO + "( " +
                "_id INTEGER PRIMARY KEY AUTOINCREMENT, "
                + "userName VARCHAR,"  //用户名
                + "nickName VARCHAR,"  //昵称
                + "sex VARCHAR,"       //性别
                + "signature VARCHAR"  //签名
                + ")" );
    }

    //数据库升级 版本号增加 升级调用此方法
    @Override
    public void onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion){
        db.execSQL("DROP TABLE IF NOT EXISTS " + U_USERINFO);
        onCreate(db);

    }
}

4、创建DBUtils工具类

选中com.boxuegu.utils包,创建一个Java类,命名为BUtilsr。用于操作数据库。代码如下
package com.boxuegu.utils;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import com.boxuegu.bean.UserBean;
import com.boxuegu.sqlite.SQLiteHelper;

public class DBUtils {
    private static SQLiteHelper helper;
    private static SQLiteDatabase db;
    private static DBUtils instance = null;
    public DBUtils(Context context) {
        helper = new SQLiteHelper(context);
        //getWritableDatabase();可写的数据库对象
        db = helper.getWritableDatabase();
    }

    public static DBUtils getInstance(Context context) {
        if (instance == null) {
            instance = new DBUtils(context);
        }
        return instance;
    }

    //保存用户个人资料信息
    public void saveUserInfo(UserBean bean) {
        ContentValues cv = new ContentValues();
        cv.put("userName", bean.userName);
        cv.put("nickName", bean.nickName);
        cv.put("sex", bean.sex);
        cv.put("signature", bean.signature);
        db.insert(SQLiteHelper.U_USERINFO, null, cv);
    }

    //获取个人资料信息
    public UserBean getUserInfo(String userName) {
    														//获取对应用户名的个人信息
        String sql = "SELECT * FROM " + SQLiteHelper.U_USERINFO + " WHERE userName=?"; 
        Cursor cursor = db.rawQuery(sql,new String[]{userName});
        UserBean bean = null;
        while (cursor.moveToNext()){
            bean = new UserBean();
            bean.userName=cursor.getString(cursor.getColumnIndex("userName"));
            bean.nickName=cursor.getString(cursor.getColumnIndex("nickName"));
            bean.sex=cursor.getString(cursor.getColumnIndex("sex"));
            bean.signature=cursor.getString(cursor.getColumnIndex("signature"));
        }
        cursor.close();
        return bean;
    }

    //修改资料
    public void updateUserInfo(String key, String value, String userName) {
        ContentValues cv = new ContentValues();
        cv.put(key, value);
        db.update(SQLiteHelper.U_USERINFO, cv, "userName = ?", new String[]{userName});
    }
    
}

5、个人资料界面逻辑代码——UserInfoActivity.java

package com.boxuegu.activity;

import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Color;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.os.Bundle;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.boxuegu.R;
import com.boxuegu.bean.UserBean;
import com.boxuegu.utils.AnalysisUtils;
import com.boxuegu.utils.DBUtils;

public class UserInfoActivity extends AppCompatActivity implements View.OnClickListener {

    private TextView tv_user_name;
    private TextView tv_signature;
    private RelativeLayout rl_signature;
    private TextView tv_sex;
    private RelativeLayout rl_sex;
    private TextView tv_nickName;
    private RelativeLayout rl_nickName;
    private TextView tv_back;
    private TextView tv_main_title;
    private RelativeLayout rl_title_bar;
    private String spUserName;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_user_info);
        //设置界面为竖屏
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        spUserName = AnalysisUtils.readLoginUserName(this);
        init();
        initData();
        setListener();
    }

    //初始化控件
    private void init() {
        tv_back = (TextView) findViewById(R.id.tv_back);
        tv_main_title = (TextView) findViewById(R.id.tv_main_title);
        tv_main_title.setText("个人资料");
        rl_title_bar = (RelativeLayout) findViewById(R.id.title_bar);
        rl_title_bar.setBackgroundColor(Color.parseColor("##FF9900"));
        rl_nickName = (RelativeLayout) findViewById(R.id.rl_nickName);
        tv_nickName = (TextView) findViewById(R.id.tv_nickName);
        rl_sex = (RelativeLayout) findViewById(R.id.rl_sex);
        tv_sex = (TextView) findViewById(R.id.tv_sex);
        rl_signature = (RelativeLayout) findViewById(R.id.rl_signature);
        tv_signature = (TextView) findViewById(R.id.tv_signature);
        tv_user_name = (TextView) findViewById(R.id.tv_user_name);
       

    }
    
    //从数据库中获取数据
    private  void initData(){
        UserBean bean = null;
        bean  = DBUtils.getInstance(this).getUserInfo(spUserName);
        //首先判断一下数据库中是否有数据
        if(bean ==null){
            bean = new UserBean();
            bean.userName = spUserName; //用户名不可以修改
            bean.nickName = "这个是你的昵称";
            //默认为男
            bean.sex = "男";
            bean.signature = "这个是你的签名";
            //保存用户信息到数据库
            DBUtils.getInstance(this).saveUserInfo(bean);
        }
        setValue(bean);
    }
    
    //为界面控件设置值
    public void setValue(UserBean bean) {
        tv_nickName.setText(bean.nickName);
        tv_sex.setText(bean.sex);
        tv_signature.setText(bean.signature);
        tv_user_name.setText(bean.userName);
    }
    
    //设置界面的点击监听事件
    private void setListener() {
        tv_back.setOnClickListener(this);
        rl_nickName.setOnClickListener(this);
        rl_sex.setOnClickListener(this);
        rl_signature.setOnClickListener(this);
    }

    //控件的点击事件
    @Override
    public void onClick(View v) {
        switch (v.getId()){
           //返回键的点击事件
            case R.id.tv_back:
                this.finish();
                break;
                
            //昵称的点击事件
            case R.id.rl_nickName:   
                break;
                
            //性别的点击事件 
            case R.id.rl_sex:
                String sex = tv_sex.getText().toString();
                sexDialog(sex);
                break;
                
            //签名的点击事件 
            case R.id.rl_signature: 
                break;
            default:
                break;
        }
    }

    //修改性别的弹出框
    private void sexDialog(String sex) {
        int sexFlag = 0;
        if("男".equals(sex)){
            sexFlag = 0;
        }else if("女".equals(sex)){
            sexFlag = 1;
        }
        final String items[] = {"男","女"};
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("性别"); //设置标题
        builder.setSingleChoiceItems(items, sexFlag, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                Toast.makeText(UserInfoActivity.this,items[which],Toast.LENGTH_SHORT).show();;
                setSex(items[which]);
            }
        });
        builder.show();
    }
    
    //更新界面上的性别数据
    private void setSex(String sex) {
        tv_sex.setText(sex);
        //更新数据库中的性别数据
        DBUtils.getInstance(this).updateUserInfo("sex",sex,spUserName);
    }
}

6、修改我的界面代码

个人资料界面是通过点击用户头像进行跳转的,找到MyInfoView.java文件的initView()方法,在注释//已登录跳转到个人资料界面下方添加如下代码:
Intent intent = new Intent(mContext, UserInfoActivity.class);
mContext.startActivity(intent);

二、资料修改界面

1、个人资料修改界面

(1)、创建个人资料修改界面

com.boxuegu.activity包中创建一个Java类。命名为ChangeUserInfoActivity。在res/layout文件夹下面创建布局文件,命名为activity_change_user_info

(2)、导入界面图片

将所需界面图片info_delete.png导入到drawable文件夹中。

(3)、资料修改界面代码——activity_change_user_info.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#eeeeee">
    <include layout="@layout/main_title_bar"/>
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:orientation="horizontal">
        <EditText
            android:id="@+id/et_content"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:layout_gravity="center_horizontal"
            android:background="@android:color/white"
            android:gravity="center_vertical"
            android:paddingLeft="10dp"
            android:singleLine="true"
            android:textColor="#737373"
            android:textSize="14sp"/>
        <ImageView
            android:id="@+id/iv_delete"
            android:layout_width="27dp"
            android:layout_height="27dp"
            android:layout_marginLeft="-40dp"
            android:src="@drawable/info_delete"/>
    </LinearLayout>

</LinearLayout>

2、资料修改界面逻辑代码——ChangeUserInfoActivity.java

package com.boxuegu.activity;

import android.content.Intent;
import android.content.pm.ActivityInfo;
import  com.boxuegu.R;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.text.Selection;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

public class ChangeUserInfoActivity extends AppCompatActivity {
    private TextView tv_main_title,tv_save;
    private RelativeLayout rl_title_bar;
    private TextView tv_back;
    private String title,content;
    private int flag;  //flag为1时表示修改昵称,为2时表示修改签名
    private EditText et_content;
    private ImageView iv_delete;
    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_change_user_info);
        //设置界面为竖屏
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        init();
    }

    private void init(){
    	//从个人资料界面传递过来的标题和内容
        title = getIntent().getStringExtra("title");
        content = getIntent().getStringExtra("content");
        flag = getIntent().getIntExtra("flag",0);
        tv_main_title = (TextView) findViewById(R.id.tv_main_title);
        tv_main_title.setText(title);
        rl_title_bar = (RelativeLayout) findViewById(R.id.title_bar);
        rl_title_bar.setBackgroundColor(Color.parseColor("#FF9900"));
        tv_back = (TextView) findViewById(R.id.tv_back);
        tv_save = (TextView) findViewById(R.id.tv_save);
        tv_save.setVisibility(View.VISIBLE);
        et_content = (EditText) findViewById(R.id.et_content);
        iv_delete = (ImageView) findViewById(R.id.iv_delete);
        if (!TextUtils.isEmpty(content)){
            et_content.setText(content);
            et_content.setSelection(content.length());
        }
        contentListener();
        tv_back.setOnClickListener(new android.view.View.OnClickListener(){
            @Override
            public void onClick(android.view.View v){
                ChangeUserInfoActivity.this.finish();
            }
        });
        iv_delete.setOnClickListener(new android.view.View.OnClickListener() {
            @Override
            public void onClick(android.view.View v) {
                et_content.setText("");
            }
        });
        tv_save.setOnClickListener(new android.view.View.OnClickListener() {
            @Override
            public void onClick(android.view.View view) {
                Intent data = new Intent();
                String etContent = et_content.getText().toString().trim();
                switch (flag){
                    case 1:
                        if (!TextUtils.isEmpty(etContent)){
                            data.putExtra("nickName",etContent);
                            setResult(RESULT_OK,data);
                            Toast.makeText(ChangeUserInfoActivity.this,"保存成功",Toast.LENGTH_SHORT).show();
                            ChangeUserInfoActivity.this.finish();
                        }else {
                            Toast.makeText(ChangeUserInfoActivity.this,"昵称不能为空",Toast.LENGTH_SHORT).show();
                        }
                        break;
                    case 2:
                        if (!TextUtils.isEmpty(etContent)){
                            data.putExtra("signature",etContent);
                            setResult(RESULT_OK,data);
                            Toast.makeText(ChangeUserInfoActivity.this,"保存成功",Toast.LENGTH_SHORT).show();
                            ChangeUserInfoActivity.this.finish();
                        }else {
                            Toast.makeText(ChangeUserInfoActivity.this,"签名不能为空",Toast.LENGTH_SHORT).show();
                        }
                        break;
                }
            }
        });
    }
    
    //监听个人资料修改界面输入的文字
    public void contentListener(){
        et_content.addTextChangedListener(new TextWatcher() {
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                Editable editable = et_content.getText();
                int len = editable.length();
                if (len>0){  //输入的文本的长度
                    iv_delete.setVisibility(View.VISIBLE);
                }else {
                    iv_delete.setVisibility(View.GONE);
                }
                switch (flag){
                    case 1:  //1代表修改昵称
                        if (len>8){    //昵称最多8个文字,超过的部分需要进行截取
                            int selEndIndex = Selection.getSelectionEnd(editable);
                            String str = editable.toString();
                            //截取新字符串
                            String newStr = str.substring(0,8);
                            et_content.setText(newStr);
                            editable = et_content.getText();
                            //新字符串的长度
                            int newLen = editable.length();
                            //旧光标位置超过新字符串的位置
                            if (selEndIndex>newLen){
                                selEndIndex = editable.length();
                            }
                            //设置新光标所在位置
                            Selection.setSelection(editable,selEndIndex);
                        }
                        break;
                        
                    case 2: //2代表修改签名
                        if (len>16){  //昵称最多16个文字,超过的部分需要进行截取
                            int selEndIndex = Selection.getSelectionEnd(editable);
                            String str = editable.toString();
                          //截取新字符串
                            String newStr = str.substring(0,16);
                            et_content.setText(newStr);
                            editable = et_content.getText();
                          //新字符串的长度
                            int newLen = editable.length();
                          //旧光标位置超过新字符串的位置
                            if (selEndIndex>newLen){
                                selEndIndex = editable.length();
                            }
                          //设置新光标所在位置
                            Selection.setSelection(editable,selEndIndex);
                        }
                        break;
                    default:
                        break;
                }
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void afterTextChanged(Editable arg0) {
            }
        });
    }

}

3、修改个人资料界面代码

(1)、找到UserInfoActivity.java文件,在 private String spUserName;后面添加以下代码:
private static  final int  CHANGE_NICKNAME = 1;//修改昵称的自定义常量
private static  final int  CHANGE_SIGNATURE = 2;//修改签名的自定义常量
(2)、找到UserInfoActivity.java文件,创建一个enterActivityForResult方法用来自定义跳转
   //自定义跳转方法 
    private void enterActivityForResult(Class<?> to,int requestCode,Bundle b){
        Intent i = new Intent(this,to);  //to标识需要跳转到的界面
        i.putExtras(b);  //b表示跳转时传递的参数
        startActivityForResult(i,requestCode);  //requestCode表示一个请求码

    }
(3)、找到UserInfoActivity.java文件,找到onClick()方法,在注释//昵称的点击事件下方添加如下代码:
String name = tv_nickName.getText().toString();//获取昵称控件上的数据
Bundle bdName = new Bundle();
bdName.putString("content",name);  //传递界面上的昵称数据
bdName.putString("title","昵称");  //传递界面的标题
bdName.putInt("flag",1);  //flag 传递1表示是昵称
//跳转到个人资料修改界面
enterActivityForResult(ChangeUserInfoActivity.class,CHANGE_NICKNAME,bdName);
(4)、找到UserInfoActivity.java文件,找到onClick()方法,在注释//签名的点击事件下方添加如下代码:
String signature = tv_signature.getText().toString();//获取签名控件上的数据
Bundle bdSignature = new Bundle();
bdSignature.putString("content",signature);//传递界面上的签名数据
bdSignature.putString("title","签名"); //传递界面的标题
bdSignature.putInt("flag",2);//flag 传递2表示是签名
//跳转到个人资料修改界面
enterActivityForResult(ChangeUserInfoActivity.class,CHANGE_SIGNATURE,bdSignature);
(5)、找到UserInfoActivity.java文件,在UserInfoActivity类中重写onActivityResult()方法,添加如下代码:
//资料修改以后回传数据到界面 
    private String new_info;  //最新数据
    @Override
    protected  void  onActivityResult(int requestCode,int resultCode,Intent data){
        super.onActivityResult(requestCode,resultCode,data);
        switch (requestCode){
            case CHANGE_NICKNAME:
                if(data!=null){
                    new_info = data.getStringExtra("nickName");//从个人资料界面回传过来的数据
                    if(TextUtils.isEmpty(new_info)||new_info==null){
                        return;
                    }
                    tv_nickName.setText(new_info);
                    //更新数据库中的呢称字段
                    DBUtils.getInstance(UserInfoActivity.this).updateUserInfo("nickName", new_info,spUserName);
                }

                break;
            case CHANGE_SIGNATURE:

                if(data!=null){
                    new_info = data.getStringExtra("signature");//从个人资料界面回传过来的数据
                    if(TextUtils.isEmpty(new_info)||new_info==null){
                        return;
                    }
                    tv_signature.setText(new_info);
                    //更新数据库中的签名字段
                    DBUtils.getInstance(UserInfoActivity.this).updateUserInfo("signature", new_info,spUserName);
                }

                break;
        }

    }

三、运行效果

在这里插入图片描述

Android项目实战系列—基于博学谷 开源地址

image               
image

猜你喜欢

转载自blog.csdn.net/weixin_42343931/article/details/105899070