五一后,被ji金伤了,哇呜呜,还是得苦逼老老实实打工写代码,看下面吧
实现登录用户名展示到用户中心页面上,并且页面有个人信息,订单列表,修改密码,意见反馈发送到服务端,前面登录后,通过SharedPreferences
把token
值保存到本地,退出登录时,用editor.clear()
直接清除保存的koten,跳转到登录界面。本篇用的技术同样是gson+okhttp
,老生常谈了,写过那么多遍,因该都懂了,哈哈~,我就当这样默认了。
一、【Android项目实战 | 从零开始写app(一)】 创建项目
二、【Android项目实战 | 从零开始写app(二)】实现闪屏页,启动app
三、【Android项目实战 | 从零开始写app(三)】实现引导页,进入登录or主页面
四、【Android项目实战 | 从零开始写app(四)】Okhttp+Gson实现服务端登录验证功能
五、【Android项目实战 | 从零开始写app(五)】okhttp+gson实现服务端注册功能
六、【Android项目实战 | 从零开始写app(六)】用TabLayout+ViewPager搭建App 框架主页面底部导航栏
七、【Android项目实战 | 从零开始写app(七)】优化主页导航栏,禁用主页页面滑动切换效果
八、【Android项目实战 | 从零开始写app(八)】实现app首页广告轮播图切换和搜索跳转
九、【Android项目实战 | 从零开始写app(九)】实现主页底部新闻模块数据的解析
十、【Android项目实战 | 从零开始写app(10)】Okhttp+glide+json+ListView实现新闻模块数据的填充显示
十一、【Android项目实战 | 从零开始写app(11)】实现app首页九宫格服务分类点击跳转
十二、【Android项目实战 | 从零开始写app(12)】实现app首页热门推荐
十三、【Android项目实战 | 从零开始写app(13)】实现服务页面数据的解析
十四、【Android项目实战 | 从零开始写app(14)】实现用户中心模块清除token退出登录&信息修改等功能
十五、【Android项目实战 | 从零开始写app(15)】实现发布模块…
在前面的基础上,继续完善项目,没有的请看前面系列文章
在UserFragment中加入下面代码:
package com.example.myapp.fragment;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.RadioGroup;
import android.widget.ScrollView;
import android.widget.TextView;
import androidx.appcompat.widget.Toolbar;
import androidx.viewpager.widget.ViewPager;
import com.example.myapp4.R;
import com.example.myapp4.activity.AdviseActivity;
import com.example.myapp4.activity.LoginActivity;
import com.example.myapp4.activity.OrderActivity;
import com.example.myapp4.activity.UpdataPSWActivity;
import com.example.myapp4.activity.UserInfoActivity;
/**
* @ProjectName: MyApp
* @Package: com.example.myapp.fragment
* @ClassName: UserFragment
* @Description:
* @Author: liyingxia
* @CreateDate: 2021/05/06 22:50
*/
public class UserFragment extends BaseFragment implements View.OnClickListener {
private static final String TAG = UserFragment.class.getSimpleName();
private TextView tv_usercenter;
private TextView tv_username;
private ImageButton user_img;
private Button btn_out;
private Intent intent = null;
private LinearLayout ll_info;
private LinearLayout ll_order;
private LinearLayout ll_update;
private LinearLayout ll_advice;
private Toolbar toolbar;
@Override
public View initView() {
Log.i(TAG, "用户中心的视图被实例化了");
View view = View.inflate(getContext(), R.layout.fragment_user, null);
ll_advice = view.findViewById(R.id.ll_advice);
ll_info = view.findViewById(R.id.ll_info);
ll_order = view.findViewById(R.id.ll_order);
ll_update = view.findViewById(R.id.ll_update);
btn_out = view.findViewById(R.id.btn_out);
tv_username = view.findViewById(R.id.tv_username);
user_img = view.findViewById(R.id.user_img);
ll_update.setOnClickListener(this);
ll_info.setOnClickListener(this);
ll_order.setOnClickListener(this);
ll_advice.setOnClickListener(this);
btn_out.setOnClickListener(this);
user_img.setOnClickListener(this);
return view;
}
/* @Override
public void onStart() {
super.onStart();
toolbar.setTitle("个人中心");
//setSupportActionBar(toolbar);
toolbar.setNavigationIcon(R.mipmap.top_bar_left_back);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// finish();
}
});
}*/
@Override
public void initData() {
super.initData();
// 读取本地保存用户的登录信息
SharedPreferences sp = getActivity().getSharedPreferences("token_data", Context.MODE_PRIVATE);
String user = sp.getString("username","");
// 把用户名显示到textView控件上
tv_username.setText(user);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.ll_info:
intent = new Intent(getContext(), UserInfoActivity.class);
break;
case R.id.ll_order:
intent = new Intent(getContext(), OrderActivity.class);
break;
case R.id.ll_update:
intent = new Intent(getContext(), UpdataPSWActivity.class);
break;
case R.id.ll_advice:
intent = new Intent(getContext(), AdviseActivity.class);
break;
case R.id.btn_out:
SharedPreferences.Editor editor = getActivity().getSharedPreferences("token_data", Context.MODE_PRIVATE).edit();
editor.clear(); // 清除本地保存的token值
editor.apply();
intent = new Intent(getContext(), LoginActivity.class);
break;
case R.id.user_img:
break;
}
// 页面跳转
startActivity(intent);
}
}
上面的editor.clear()
实现清除本地保存的token值,最后记得apply()提交。其他都是简单点击实现页面跳转。
用户中心页面布局,一些文本text,color等资源应该放到style目录下,方便后期维护修改,比较统一,但我没有这样做,就直接这样写了,你们可以自己实现,不清楚的看我前面文章:Android 实现国际化效果
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_usercenter"
android:layout_width="match_parent"
android:layout_height="45dp"
android:background="#22349C"
android:gravity="center"
android:padding="10dp"
android:text="个人中心"
android:textColor="#fff"
android:textSize="20sp" />
<LinearLayout
android:layout_below="@id/tv_usercenter"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="170dp"
android:background="#3F51B5">
<ImageButton
android:id="@+id/user_img"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerInParent="true"
android:background="@mipmap/top_image_icon" />
<TextView
android:id="@+id/tv_username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="130dp"
android:text="我是李子哈"
android:textColor="#ffffff" />
RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="8dp"
android:background="#eee" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:id="@+id/ll_info"
android:orientation="horizontal">
<TextView
style="@style/TextStyle"
android:text="个人信息" />
<ImageButton
android:id="@+id/ib_user_info"
android:layout_width="40dp"
android:layout_marginLeft="230dp"
android:layout_height="40dp"
android:background="@null"
android:src="@mipmap/home_arrow_right"/>
LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginLeft="45dp"
android:background="#eee" />
<LinearLayout
android:id="@+id/ll_order"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:orientation="horizontal">
<TextView
style="@style/TextStyle"
android:text="订单列表" />
<ImageButton
android:id="@+id/ib_order_list"
android:layout_gravity="left"
android:layout_width="40dp"
android:layout_marginLeft="230dp"
android:layout_height="40dp"
android:background="@null"
android:src="@mipmap/home_arrow_right"/>
LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginLeft="45dp"
android:background="#eee" />
<LinearLayout
android:id="@+id/ll_update"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:baselineAligned="false"
android:orientation="horizontal">
<TextView
style="@style/TextStyle"
android:text="修改密码" />
<ImageButton
android:layout_gravity="left"
android:layout_width="40dp"
android:id="@+id/ib_update_psw"
android:layout_marginLeft="230dp"
android:layout_height="40dp"
android:background="@null"
android:src="@mipmap/home_arrow_right"/>
LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginLeft="45dp"
android:background="#eee" />
<LinearLayout
android:id="@+id/ll_advice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:baselineAligned="false"
android:orientation="horizontal">
<TextView
style="@style/TextStyle"
android:text="意见反馈" />
<ImageButton
android:layout_gravity="left"
android:layout_width="40dp"
android:id="@+id/ib_advise"
android:layout_marginLeft="230dp"
android:layout_height="40dp"
android:background="@null"
android:src="@mipmap/home_arrow_right"/>
LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginLeft="45dp"
android:background="#eee" />
<Button
android:layout_margin="15dp"
android:layout_width="match_parent"
android:layout_height="40dp"
android:text="退出账号"
android:textStyle="bold"
android:textColor="#ffffff"
android:background="#A3184FF1"
android:id="@+id/btn_out"/>
LinearLayout>
RelativeLayout>
意见反馈页面
package com.example.myapp4.activity;
import android.annotation.SuppressLint;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import com.example.myapp.R;
import com.example.myapp.utils.APIConfig;
import com.example.myapp.utils.GetToken;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class AdviseActivity extends AppCompatActivity implements View.OnClickListener {
private ImageButton btn_back;
private EditText content;
private Button btn_send;
// 更新主线程的UI
@SuppressLint("HandlerLeak")
private Handler handler = new Handler(){
// 接收消息
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if (msg.what==1) {
String re = msg.obj.toString();
Toast.makeText(getApplicationContext(),"反馈成功:"+re,Toast.LENGTH_LONG).show();
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_advise);
initView();
}
private void initView() {
btn_back = (ImageButton) findViewById(R.id.btn_back);
content = (EditText) findViewById(R.id.content);
btn_send = (Button) findViewById(R.id.btn_send);
btn_back.setOnClickListener(this);
btn_send.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_back:
finish();
break;
case R.id.btn_send:
SendAdavice();
break;
}
}
// 发送建议反馈到服务端
private void SendAdavice() {
String contentString = content.getText().toString().trim();
if (TextUtils.isEmpty(contentString)) {
Toast.makeText(this, "内容不能为空", Toast.LENGTH_SHORT).show();
return;
}
// 获取SharedPreferences对象
SharedPreferences sp = this.getSharedPreferences("token_data",MODE_PRIVATE);
String token = sp.getString("token","");
// 实例化OkHttpClient 对象
OkHttpClient client = new OkHttpClient();
// 实例化 JSONObject
JSONObject object = new JSONObject();
try {
object.put("content",contentString);
object.put("userid",8888);
} catch (JSONException e) {
e.printStackTrace();
}
// 设置传递的数据类型
MediaType mediaType = MediaType.parse("application/json;charset=utf-8");
RequestBody requestBody = RequestBody.create(mediaType,object.toString());
Request request = new Request.Builder()
.post(requestBody)
.url(APIConfig.BASE_URL+"/userinfo/feedback")
.addHeader("Authorization",token)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
// 响应失败
@Override
public void onFailure(Call call, IOException e) {
Log.i("onFailure",e.getMessage());
}
// 响应成功
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
String result = response.body().string();
// 创建Message 对象
Message msg = new Message();
/*
* what是自定义的一个Message的识别码,以便于在Handler的handleMessage方 *法中根据what识别出不同的Message,以便我们做出不同的处理操作
*/
msg.what=1;
// 通过给obj赋值Object类型传递向Message传入请求到的数据
msg.obj=result;
// 发送消息
handler.sendMessage(msg);
}
}
});
}
}
MediaType指的是要传递的数据的MIME
类型,MediaType对象包含了三种信息:type
、subtype
以及charset
,一般将这些信息传入parse()
方法中,这样就可以解析出MediaType对象,比如 “application/json; charset=utf-8” ,用来告诉服务端消息主体是序列化后的 JSON 字符串 charset=utf-8 则表示采用UTF-8编码。如果不知道某种类型数据的MIME类型,可以参见Media Type和MIME 参考手册,这里不再多说。
这里用Handler 处理异步消息处理,它的主要作用:消息处理者,主要用于发送跟处理消息,发送消息:SendMessage()
,处理消息: HandleMessage()
在子线程
中更新主线程的UI。
Handler是android线程之间的消息机制,主要的作用是将一个任务切换到指定的线程中去执行,(准确的说是切换到构成handler的looper所在的线程中去出处理)android系统中的一个例子就是主线程中的所有操作都是通过主线程中的handler去处理的。
上面的msg.what=1
中的what是自定义的一个Message的识别码,以便于在Handler的handleMessage方法中根据what识别出不同的Message,以便我们做出不同的处理操作。通过给obj赋值Object类型传递向Message传入请求到的数据。
<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:orientation="vertical"
android:layout_height="match_parent"
tools:context=".activity.AdviseActivity">
<RelativeLayout
android:layout_margin="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageButton
android:id="@+id/btn_back"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="@null"
android:layout_alignParentLeft="true"
android:src="@mipmap/top_bar_left_back1"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="意见反馈"
android:textStyle="bold"
android:layout_toRightOf="@id/btn_back"
android:textColor="#000000"
android:textSize="20sp"
android:gravity="center"/>
RelativeLayout>
<LinearLayout
android:layout_margin="20dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/login_form_bg">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:text="请输入您的意见:"/>
<EditText
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="@null"
android:id="@+id/content"
android:hint=""/>
LinearLayout>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="提交"
android:id="@+id/btn_send"
android:layout_margin="20dp"
android:textColor="#fff"
android:textSize="22sp"
android:background="@drawable/login_btn_bg"/>
LinearLayout>
UpdataPSWActivity:
package com.example.myapp4.activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.example.myapp4.R;
import com.example.myapp4.bean.LoginBean;
import com.example.myapp4.bean.UserBean;
import com.example.myapp4.utils.APIConfig;
import com.google.gson.Gson;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class UpdataPSWActivity extends AppCompatActivity implements View.OnClickListener {
private ImageButton btn_back;
private EditText userId;
private EditText et_old_psw;
private EditText et_new_psw;
private Button btn_update;
private Button btn_clear;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_updata_psw);
initView();
}
private void initView() {
btn_back = (ImageButton) findViewById(R.id.btn_back);
userId = (EditText) findViewById(R.id.userId);
et_old_psw = (EditText) findViewById(R.id.et_old_psw);
et_new_psw = (EditText) findViewById(R.id.et_new_psw);
btn_update = (Button) findViewById(R.id.btn_update);
btn_clear = (Button) findViewById(R.id.btn_clear);
btn_back.setOnClickListener(this);
btn_update.setOnClickListener(this);
btn_clear.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_back:
finish();
break;
case R.id.btn_update:
Update();
break;
case R.id.btn_clear:
userId.setText("");
et_old_psw.setText("");
et_new_psw.setText("");
break;
}
}
private void Update() {
String userIdString = userId.getText().toString().trim();
if (TextUtils.isEmpty(userIdString)) {
Toast.makeText(this, "请输入你的用户编号", Toast.LENGTH_SHORT).show();
return;
}
String old_password = et_old_psw.getText().toString().trim();
if (TextUtils.isEmpty(old_password)) {
Toast.makeText(this, "请输入你的原始密码", Toast.LENGTH_SHORT).show();
return;
}
String password = et_new_psw.getText().toString().trim();
if (TextUtils.isEmpty(password)) {
Toast.makeText(this, "请输入你的新密码", Toast.LENGTH_SHORT).show();
return;
}
SharedPreferences sp = getSharedPreferences("token_data",MODE_PRIVATE);
String user_psw = sp.getString("password","");
String token = sp.getString("token","");
OkHttpClient client = new OkHttpClient();
JSONObject json = new JSONObject();
try {
json.put("userId",userIdString);
json.put("oldPwd",old_password);
json.put("password",password);
} catch (JSONException e) {
e.printStackTrace();
}
MediaType mediaType = MediaType.parse("application/json;charset=utf-8");
RequestBody requestBody = RequestBody.create(mediaType,json.toString());
Request request = new Request.Builder()
.url(APIConfig.BASE_URL+"/system/user/resetPwd")
.addHeader("Authorization",token)
.post(requestBody)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.i("请求失败",e.getMessage());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
String result = response.body().string();
Gson gson = new Gson();
LoginBean loginBean = gson.fromJson(result,LoginBean.class);
String code = loginBean.getCode();
if (code=="200") {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(UpdataPSWActivity.this,"密码更新成功:"+result,Toast.LENGTH_LONG).show();
}
});
}
}
}
});
}
}
<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:background="#EFEDED"
android:orientation="vertical">
<RelativeLayout
android:layout_margin="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageButton
android:id="@+id/btn_back"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="@null"
android:layout_alignParentLeft="true"
android:src="@mipmap/top_bar_left_back1"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="修改密码"
android:textStyle="bold"
android:layout_centerHorizontal="true"
android:layout_toRightOf="@id/btn_back"
android:textColor="#000000"
android:textSize="20sp"
android:gravity="center"/>
RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#F6F5F4"
/>
<LinearLayout
android:layout_marginRight="20dp"
android:layout_marginLeft="20dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/login_form_bg"
android:orientation="vertical">
<LinearLayout
android:layout_marginTop="12dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="用户编号:"
android:layout_marginTop="10dp"
android:textSize="18sp"
android:textColor="#000000"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/userId"
android:textSize="16sp"
android:background="@null"
android:layout_margin="5dp"
android:hint="请输入你的用户编号"/>
LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="15dp"
android:background="#F6F5F4"
/>
<LinearLayout
android:layout_marginTop="12dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="原始密码:"
android:layout_marginTop="10dp"
android:textSize="18sp"
android:textColor="#000000"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/et_old_psw"
android:textSize="16sp"
android:background="@null"
android:layout_margin="5dp"
android:hint="请输入你的原始密码"/>
LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="15dp"
android:background="#F6F5F4"
/>
<LinearLayout
android:layout_marginTop="12dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="10dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="新密码:"
android:layout_marginTop="10dp"
android:textSize="18sp"
android:textColor="#000000"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/et_new_psw"
android:textSize="16sp"
android:background="@null"
android:layout_margin="5dp"
android:hint="请输入你的新密码"/>
LinearLayout>
LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:orientation="vertical">
<Button
android:id="@+id/btn_update"
android:layout_marginTop="50dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="确定"
android:textSize="20sp"
android:textColor="#ffffff"
android:background="@drawable/login_btn_bg"/>
<Button
android:id="@+id/btn_clear"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="清空"
android:textSize="18sp"
android:textColor="#2196F3"
android:background="@drawable/login_form_bg"/>
LinearLayout>
LinearLayout>
修改个人信息属于个人隐私的数据,在请求服务端数据时,需要在okhttp
中的addHeader("Authorization",token)
请求头带上Authorization
标识的token值来验证请求。
package com.example.myapp.activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.example.myapp.R;
import com.example.myapp.bean.ResponseBean;
import com.example.myapp.utils.APIConfig;
import com.google.gson.Gson;
import org.json.JSONObject;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class UserInfoActivity extends AppCompatActivity implements View.OnClickListener {
private ImageButton btn_back;
private ImageView ib_img;
private EditText et_nicke;
private EditText et_phone;
private EditText et_email;
private EditText et_idetity;
private RadioButton rb_man;
private RadioButton rb_woman;
private RadioGroup rg_sex;
private Button btn_update;
private Button btn_clear;
private String sex = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_info);
initView();
}
private void initView() {
btn_back = (ImageButton) findViewById(R.id.btn_back);
ib_img = (ImageView) findViewById(R.id.ib_img);
et_nicke = (EditText) findViewById(R.id.et_nicke);
et_phone = (EditText) findViewById(R.id.et_phone);
et_email = (EditText) findViewById(R.id.et_email);
et_idetity = (EditText) findViewById(R.id.et_idetity);
rb_man = (RadioButton) findViewById(R.id.rb_man);
rb_woman = (RadioButton) findViewById(R.id.rb_woman);
rg_sex = (RadioGroup) findViewById(R.id.rg_sex);
btn_update = (Button) findViewById(R.id.btn_update);
btn_clear = (Button) findViewById(R.id.btn_clear);
btn_back.setOnClickListener(this);
btn_update.setOnClickListener(this);
btn_clear.setOnClickListener(this);
rg_sex.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
if (rb_man.isChecked()) {
sex = "1";
} else {
sex = "0";
}
}
});
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_back:
finish();
break;
case R.id.btn_update:
UpdateInfo();
break;
case R.id.btn_clear:
// 清空
et_nicke.setText("");
et_phone.setText("");
et_phone.setText("");
et_idetity.setText("");
et_email.setText("");
sex = "";
break;
}
}
private void UpdateInfo() {
//输入校验
String nicke = et_nicke.getText().toString().trim();
if (TextUtils.isEmpty(nicke)) {
Toast.makeText(this, "请输入昵称", Toast.LENGTH_SHORT).show();
return;
}
String phone = et_phone.getText().toString().trim();
if (TextUtils.isEmpty(phone)) {
Toast.makeText(this, "请输入你的手机号码", Toast.LENGTH_SHORT).show();
return;
}
String email = et_email.getText().toString().trim();
if (TextUtils.isEmpty(email)) {
Toast.makeText(this, "请输入你的邮箱地址", Toast.LENGTH_SHORT).show();
return;
}
String idetity = et_idetity.getText().toString().trim();
if (TextUtils.isEmpty(idetity)) {
Toast.makeText(this, "4405281999121411040640", Toast.LENGTH_SHORT).show();
return;
}
if (TextUtils.isEmpty(sex)){
Toast.makeText(this, "请选择你的性别", Toast.LENGTH_SHORT).show();
return;
}
SharedPreferences sp = this.getSharedPreferences("token_data",MODE_PRIVATE);
String token = sp.getString("token","");
String username = sp.getString("username","");
// 实例化 OkHttpClient
OkHttpClient client = new OkHttpClient();
// 实例化 JSONObject
JSONObject object = new JSONObject();
try {
object.put("userId",111);
object.put("idCard",idetity);
object.put("userName",username);
object.put("nickName",nicke);
object.put("phonenumber",phone);
object.put("email",email);
object.put("sex",sex);
object.put("file","");
object.put("remark","");
} catch (Exception e) {
e.printStackTrace();
}
// 设置 MediaType参数
MediaType mediaType = MediaType.parse("application/json;charset=utf-8");
// 请求体
RequestBody requestBody = RequestBody.create(mediaType,object.toString());
Request request = new Request.Builder()
.url(APIConfig.BASE_URL+"/system/user/updata") // 请求url
.post(requestBody) // post 请求发送数据到服务端
.addHeader("Authorization",token) 带上token 请求头
.build();
Call call = client.newCall(request); // 请求回调
call.enqueue(new Callback() {
// 异步请求
// 请求失败
@Override
public void onFailure(Call call, IOException e) {
Log.i("请求失败",e.getMessage());
}
// 响应成功
@Override
public void onResponse(Call call, Response response) throws IOException {
// 成功
if (response.isSuccessful()) {
Gson gson = new Gson();
String result = response.body().string();
ResponseBean responseBean = gson.fromJson(result,ResponseBean.class);
String code = responseBean.getCode();
if (code=="200") {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(),"用户信息修改成功:"+result,Toast.LENGTH_LONG).show();;
}
});
}
}
}
});
}
}
<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:layout_margin="10dp"
android:orientation="vertical">
<RelativeLayout
android:layout_margin="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageButton
android:id="@+id/btn_back"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="@null"
android:layout_alignParentLeft="true"
android:src="@mipmap/top_bar_left_back1"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="用户信息"
android:textStyle="bold"
android:layout_centerHorizontal="true"
android:layout_toRightOf="@id/btn_back"
android:textColor="#000000"
android:textSize="20sp"
android:gravity="center"/>
RelativeLayout>
<LinearLayout
android:background="@drawable/login_form_bg"
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:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我的头像"
android:layout_marginTop="10dp"
android:textSize="18sp"
android:paddingRight="16dp"
android:textColor="#000000"/>
<ImageView
android:id="@+id/ib_img"
android:layout_width="60dp"
android:layout_height="60dp"
android:src="@mipmap/top_image_icon"/>
LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="15dp"
android:background="#F6F5F4"
/>
<LinearLayout
android:layout_marginTop="12dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我的昵称"
android:layout_marginTop="10dp"
android:textSize="18sp"
android:textColor="#000000"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/et_nicke"
android:textSize="16sp"
android:background="@null"
android:layout_margin="5dp"
android:hint="请输入昵称"/>
LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="15dp"
android:background="#F6F5F4"
/>
<LinearLayout
android:layout_marginTop="12dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="联系电话"
android:layout_marginTop="10dp"
android:textSize="18sp"
android:textColor="#000000"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/et_phone"
android:textSize="16sp"
android:background="@null"
android:layout_margin="5dp"
android:hint="请输入你的手机号码"/>
LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="15dp"
android:background="#F6F5F4"
/>
<LinearLayout
android:layout_marginTop="12dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="邮箱地址"
android:layout_marginTop="10dp"
android:textSize="18sp"
android:textColor="#000000"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/et_email"
android:textSize="16sp"
android:background="@null"
android:layout_margin="5dp"
android:hint="请输入你的邮箱地址"/>
LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="15dp"
android:background="#F6F5F4"
/>
<LinearLayout
android:layout_marginTop="12dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="证件信息"
android:layout_marginTop="10dp"
android:textSize="18sp"
android:textColor="#000000"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/et_idetity"
android:textSize="16sp"
android:background="@null"
android:layout_margin="5dp"
android:hint="4405281999121411040640"/>
LinearLayout>
<View
android:layout_marginTop="15dp"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#F6F5F4"
/>
<LinearLayout
android:layout_marginTop="12dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="你的性别"
android:layout_marginTop="10dp"
android:textSize="18sp"
android:textColor="#000000"/>
<RadioGroup
android:id="@+id/rg_sex"
android:layout_marginBottom="20dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:orientation="horizontal">
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="男"
android:layout_marginRight="40dp"
android:id="@+id/rb_man"/>
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="女"
android:id="@+id/rb_woman"/>
RadioGroup>
LinearLayout>
LinearLayout>
<Button
android:id="@+id/btn_update"
android:layout_marginTop="50dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="修改"
android:textSize="20sp"
android:textColor="#ffffff"
android:background="@drawable/login_btn_bg"/>
<Button
android:id="@+id/btn_clear"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="清空"
android:textSize="20sp"
android:textColor="#107FD8"
android:background="@drawable/login_form_bg"/>
LinearLayout>
在bean目录下新家LoginBean.class 实体类,gson解析json数据会用到
public class LoginBean {
/**
* msg : 操作成功
* code : 200
* token : eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6ImMyYjE1YTNkLTlkNWQtNGFmZi04MGU3LTNlNWMxYTdkYzcyNSJ9.sZxcMsSvH7F50jCpTdtrv296mgq5IOI8OAo8rAXDQ4mw7KssvPsdwFcFdxHyGodfYmrsDxv0wyyEgDdl7JDxoQ
*/
private String msg;
private String code;
private String token;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public LoginBean(String msg, String code, String token) {
this.msg = msg;
this.code = code;
this.token = token;
}
@Override
public String toString() {
return "UserLogin{" +
"msg='" + msg + '\'' +
", code=" + code +
", token='" + token + '\'' +
'}';
}
}
个人订单跟解析新闻数据差不多,不过个人订单属于个人隐私的数据,在请求服务端数据时,需要在okhttp
中的addHeader("Authorization",token)
请求头带上Authorization
标识的token值来验证请求。
public class OrderActivity extends AppCompatActivity {
private Toolbar toolbar;
private ListView order_listView;
private OrderBean orderBean;
/* private Handler handler = new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if (msg.what==1) {
String result = msg.obj.toString();
Gson gson = new Gson();
orderBean = gson.fromJson(result,OrderBean.class);
OrderAdapter orderAdapter = new OrderAdapter();
order_listView.setAdapter(orderAdapter);
order_listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView> adapterView, View view, int i, long l) {
Toast.makeText(getApplication(),"你点击了:"+i,Toast.LENGTH_LONG).show();
}
});
}
}
};*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_order);
toolbar = findViewById(R.id.toolbar);
order_listView = findViewById(R.id.order_listView);
getHttp();
}
private void getHttp() {
// 请求参数
int pageNum = 1;
int pageSize = 10;
int userId = 1;
实例化 OkHttpClient 对象
OkHttpClient client = new OkHttpClient();
// 读取本地保存的token 值
SharedPreferences sp = getSharedPreferences("token_data",MODE_PRIVATE);
String token =sp.getString("token","");
// 创建JSONObject 对象
JSONObject object = new JSONObject();
try {
// 带上请求体参数
object.put("pageNum",1);
object.put("pageSize",10);
object.put("userId",1);
} catch (JSONException e) {
e.printStackTrace();
}
// 设置 MediaType参数
MediaType mediaType = MediaType.parse("application/json;charset=utf-8");
// 请求体
RequestBody requestBody = RequestBody.create(mediaType,object.toString());
String url = APIConfig.BASE_URL+"/userinfo/orders/list"+"?"+pageNum+"&"+pageSize+"&"+userId;
Request request = new Request.Builder()
.url(url)
.addHeader("Authorization",token)
.build();
// 请求回调
Call call = client.newCall(request);
// 重写异步请求
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.i("onFailure",e.getMessage());
}
// 请求响应成功
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
String result = response.body().string();
Log.i("请求成功",result);
runOnUiThread(new Runnable() {
@Override
public void run() {
// gson解析请求到的数据
Gson gson = new Gson();
orderBean = gson.fromJson(result,OrderBean.class);
OrderAdapter orderAdapter = new OrderAdapter();
order_listView.setAdapter(orderAdapter);
order_listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Toast.makeText(getApplication(),"你点击了"+i,Toast.LENGTH_LONG).show();
}
});
}
});
}
}
});
}
@Override
protected void onStart() {
super.onStart();
// 顶部标题栏
toolbar.setTitle("订单列表");
setSupportActionBar(toolbar);
// 设置标题栏图标
toolbar.setNavigationIcon(R.mipmap.top_bar_left_back);
toolbar.setTitleMarginEnd(200);
// 点击事件
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
}
public class OrderAdapter extends BaseAdapter {
// item 数据
@Override
public int getCount() {
return orderBean.getData().size();
}
@Override
public Object getItem(int i) {
return orderBean.getData().get(i);
}
@Override
public long getItemId(int i) {
return i;
}
// 每项item布局
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
HolderView holderView;
if (view==null) {
view = View.inflate(getApplicationContext(),R.layout.order_item,null);
holderView = new HolderView();
holderView.tv_ordernum = view.findViewById(R.id.tv_ordernum);
holderView.order_date = view.findViewById(R.id.order_date);
holderView.order_type = view.findViewById(R.id.order_type);
view.setTag(holderView);
} else {
holderView = (HolderView) view.getTag();
}
holderView.order_date.setText(orderBean.getData().get(i).getCreateTime());
holderView.tv_ordernum.setText(orderBean.getData().get(i).getOrderNum());
holderView.order_type.setText("地铁");
return view;
}
// 优化ListView
class HolderView{
TextView tv_ordernum;
TextView order_date;
TextView order_type;
}
}
}
基本都注释了,我们都知道在Android中不能在主线程进行网络请求等耗时操作,而且Ui控件的更新不能在工作线程中操作,所以通过 runOnUiThread
这个方法来更新UI界面。当然跟新Ui还有其他方式例如:使用AsyncTask
、Handler
等,这里不做深究。如果在fragment中,记得通过getActivity
获取当前
<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=".activity.OrderActivity">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/toolbar"
app:titleTextColor="#fff"
android:background="@color/blue"/>
<ListView
android:layout_width="match_parent"
android:divider="#000"
android:layout_height="wrap_content"
android:id="@+id/order_listView" />
LinearLayout>
接下来就是ListView 适配器子项item布局:
<LinearLayout
android:padding="4dp"
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:background="@drawable/login_form_bg"
android:orientation="vertical"
android:layout_marginRight="20dp">
<LinearLayout
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="订单编号:"/>
<TextView
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="100000000"
android:id="@+id/tv_ordernum"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2021-03-28 23:45:34"
android:id="@+id/order_date"/>
LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="订单类型:"
android:layout_marginTop="10dp"
android:id="@+id/order_type0"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="交通出行"
android:layout_marginTop="10dp"
android:id="@+id/order_type"/>
LinearLayout>
LinearLayout>
LinearLayout>
public class OrderBean implements Serializable {
/**
* msg : 操作成功
* code : 200
* data : [{"searchValue":null,"createBy":null,"createTime":"2020-10-24 19:23:31","updateBy":null,"updateTime":null,"remark":null,"params":{},"orderNum":"60353861","id":1,"path":"三号线","start":"珠江新城","end":"广州北站","price":8,"userName":"张三","userTel":"12345611","userId":1,"status":0},{"searchValue":null,"createBy":null,"createTime":"2020-10-24 19:25:36","updateBy":null,"updateTime":null,"remark":null,"params":{},"orderNum":"60353873","id":2,"path":"三号线","start":"珠江新城","end":"大连北站","price":8,"userName":"张三","userTel":"12345611","userId":1,"status":0}]
*/
private String msg;
private int code;
private List<OrderData> data;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public List<OrderData> getData() {
return data;
}
public void setData(List<OrderData> data) {
this.data = data;
}
public static class OrderData {
/**
* searchValue : null
* createBy : null
* createTime : 2020-10-24 19:23:31
* updateBy : null
* updateTime : null
* remark : null
* params : {}
* orderNum : 60353861
* id : 1
* path : 一号线
* start : 泰德大厦
* end : 大连北站
* price : 8
* userName : 张三
* userTel : 12345611
* userId : 1
* status : 0
*/
private Object searchValue;
private Object createBy;
private String createTime;
private Object updateBy;
private Object updateTime;
private Object remark;
private String orderNum;
private int id;
private String path;
private String start;
private String end;
private int price;
private String userName;
private String userTel;
private int userId;
private int status;
public Object getSearchValue() {
return searchValue;
}
public void setSearchValue(Object searchValue) {
this.searchValue = searchValue;
}
public Object getCreateBy() {
return createBy;
}
public void setCreateBy(Object createBy) {
this.createBy = createBy;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
public Object getUpdateBy() {
return updateBy;
}
public void setUpdateBy(Object updateBy) {
this.updateBy = updateBy;
}
public Object getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Object updateTime) {
this.updateTime = updateTime;
}
public Object getRemark() {
return remark;
}
public void setRemark(Object remark) {
this.remark = remark;
}
public String getOrderNum() {
return orderNum;
}
public void setOrderNum(String orderNum) {
this.orderNum = orderNum;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getStart() {
return start;
}
public void setStart(String start) {
this.start = start;
}
public String getEnd() {
return end;
}
public void setEnd(String end) {
this.end = end;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserTel() {
return userTel;
}
public void setUserTel(String userTel) {
this.userTel = userTel;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public OrderData(String createTime, String orderNum) {
this.createTime = createTime;
this.orderNum = orderNum;
}
}
}