【0100】【项目实战】-【Android互动直播APP开发】-【3】用户中心开发与APP主界面搭建
1. APP页面需要实现的内容

2.登陆注册界面的实现

2.1 新建工程/登陆注册界面布局






1 <?xml version="1.0" encoding="utf-8"?> 2 3 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 4 android:id="@+id/activity_login" 5 android:layout_width="match_parent" 6 android:layout_height="match_parent" 7 android:background="@android:color/white"> 8 9 <LinearLayout 10 android:layout_width="match_parent" 11 android:layout_height="wrap_content" 12 android:layout_centerInParent="true" 13 android:background="@android:color/white" 14 android:gravity="center_horizontal" 15 android:orientation="vertical"> 16 17 <ImageView 18 android:layout_width="wrap_content" 19 android:layout_height="wrap_content" 20 android:layout_gravity="center_horizontal" 21 android:layout_marginBottom="20dp" 22 android:layout_marginTop="30dp" 23 android:src="@mipmap/ic_launcher" /> 24 25 <LinearLayout 26 android:layout_width="match_parent" 27 android:layout_height="wrap_content" 28 android:gravity="center_vertical" 29 android:orientation="horizontal" 30 android:paddingBottom="15dp" 31 android:paddingLeft="30dp" 32 android:paddingRight="30dp" 33 android:paddingTop="30dp"> 34 35 <TextView 36 android:layout_width="0dp" 37 android:layout_height="wrap_content" 38 android:layout_weight="1" 39 android:gravity="center" 40 android:drawableLeft="@drawable/ic_account"/> 41 42 <EditText 43 android:id="@+id/account" 44 android:layout_width="0dp" 45 android:layout_height="wrap_content" 46 android:layout_weight="4" 47 android:background="@android:color/transparent" 48 android:hint="请输入用户名" 49 android:textColor="@android:color/black" 50 android:textColorHint="#ccc" 51 android:textSize="16sp" /> 52 </LinearLayout> 53 54 55 <View 56 android:layout_width="match_parent" 57 android:layout_height="1px" 58 android:background="#3000" /> 59 60 61 <LinearLayout 62 android:layout_width="match_parent" 63 android:layout_height="wrap_content" 64 android:gravity="center_vertical" 65 android:orientation="horizontal" 66 android:paddingBottom="30dp" 67 android:paddingLeft="30dp" 68 android:paddingRight="30dp" 69 android:paddingTop="15dp"> 70 71 <TextView 72 android:layout_width="0dp" 73 android:layout_height="wrap_content" 74 android:layout_weight="1" 75 android:drawableLeft="@drawable/ic_password" /> 76 77 <EditText 78 android:id="@+id/password" 79 android:layout_width="0dp" 80 android:layout_height="wrap_content" 81 android:layout_weight="4" 82 android:background="@android:color/transparent" 83 android:hint="请输入密码" 84 android:inputType="textPassword" 85 android:textColor="@android:color/black" 86 android:textColorHint="#ccc" 87 android:textSize="16sp" /> 88 </LinearLayout> 89 90 <Button 91 android:id="@+id/login" 92 android:layout_width="match_parent" 93 android:layout_height="40dp" 94 android:layout_marginLeft="50dp" 95 android:layout_marginRight="50dp" 96 android:layout_marginTop="10dp" 97 android:background="@drawable/btn_bkg_red_rect_round" 98 android:text="登录" 99 android:textColor="@color/colorPrimaryDark" /> 100 101 <Button 102 android:id="@+id/register" 103 android:layout_width="wrap_content" 104 android:layout_height="wrap_content" 105 android:layout_marginTop="10dp" 106 android:background="@android:color/transparent" 107 android:text="注册新用户" 108 android:textColor="@android:color/holo_blue_dark" /> 109 </LinearLayout> 110 111 </RelativeLayout>

2.2 登陆的逻辑


【参考腾讯云的登陆逻辑】





【说明】分为三步:初始化sdk--tlsLogin--iLiveLogin


【APP初始化】新建类;

【添加引用库】
[参考]


[增加引用库]

【导库】

【初始化的参数】




【添加登陆接口的调用】
[拷贝登陆的源码]

[维护自己的代码]



【源码】
1 private void setListeners() { 2 mLoginBtn.setOnClickListener(new View.OnClickListener() { 3 @Override 4 public void onClick(View v) { 5 //登录操作 6 login(); 7 } 8 }); 9 10 private void login() { 11 final String accountStr = mAccountEdt.getText().toString(); 12 String passwordStr = mPasswordEdt.getText().toString(); 13 14 //调用腾讯IM登录 15 ILiveLoginManager.getInstance().tlsLogin(accountStr, passwordStr, new ILiveCallBack<String>() { 16 @Override 17 public void onSuccess(String data) { 18 //登陆成功。 19 loginLive(accountStr, data); 20 } 21 22 @Override 23 public void onError(String module, int errCode, String errMsg) { 24 //登录失败 25 Toast.makeText(LoginActivity.this, "tls登录失败:" + errMsg, Toast.LENGTH_SHORT).show(); 26 } 27 }); 28 } 29 30 private void loginLive(String accountStr, String data) { 31 ILiveLoginManager.getInstance().iLiveLogin(accountStr, data, new ILiveCallBack() { 32 33 @Override 34 public void onSuccess(Object data) { 35 //最终登录成功 36 Toast.makeText(LoginActivity.this, "登录成功!", Toast.LENGTH_SHORT).show(); 37 Intent intent = new Intent(); 38 intent.setClass(LoginActivity.this, MainActivity.class); 39 startActivity(intent); 40 41 getSelfInfo(); 42 43 finish(); 44 } 45 46 @Override 47 public void onError(String module, int errCode, String errMsg) { 48 //登录失败 49 Toast.makeText(LoginActivity.this, "iLive登录失败:" + errMsg, Toast.LENGTH_SHORT).show(); 50 51 } 52 }); 53 }
2.3 注册的逻辑

【创建空的Activit】创建activity,而不是创建了class,因为创建activity可以直接在清单文件中已经配置好了,没有必要在配置了;


【布局】
【注意】注册同意textView的点击事件在源码没有实现;

1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:id="@+id/activity_register" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent" 6 android:orientation="vertical"> 7 8 <android.support.v7.widget.Toolbar 9 android:id="@+id/titlebar" 10 android:layout_width="match_parent" 11 android:layout_height="?attr/actionBarSize" 12 android:background="@color/colorPrimaryDark" /> 13 14 <LinearLayout 15 android:layout_width="match_parent" 16 android:layout_height="wrap_content" 17 android:gravity="center_vertical" 18 android:orientation="horizontal" 19 android:paddingBottom="15dp" 20 android:paddingLeft="30dp" 21 android:paddingRight="30dp" 22 android:paddingTop="30dp"> 23 24 <TextView 25 android:layout_width="0dp" 26 android:layout_height="wrap_content" 27 android:layout_weight="1" 28 android:drawableLeft="@drawable/ic_account" /> 29 30 <EditText 31 android:id="@+id/account" 32 android:layout_width="0dp" 33 android:layout_height="wrap_content" 34 android:layout_weight="5" 35 android:background="@android:color/transparent" 36 android:hint="请输入注册账号(至少为8个字符)" 37 android:textColor="@android:color/black" 38 android:textColorHint="#ccc" 39 android:textSize="16sp" /> 40 </LinearLayout> 41 42 <View 43 android:layout_width="match_parent" 44 android:layout_height="1px" 45 android:background="#3000" /> 46 47 <LinearLayout 48 android:layout_width="match_parent" 49 android:layout_height="wrap_content" 50 android:gravity="center_vertical" 51 android:orientation="horizontal" 52 android:paddingBottom="15dp" 53 android:paddingLeft="30dp" 54 android:paddingRight="30dp" 55 android:paddingTop="15dp"> 56 57 <TextView 58 android:layout_width="0dp" 59 android:layout_height="wrap_content" 60 android:layout_weight="1" 61 android:drawableLeft="@drawable/ic_password" /> 62 63 <EditText 64 android:id="@+id/password" 65 android:layout_width="0dp" 66 android:layout_height="wrap_content" 67 android:layout_weight="5" 68 android:background="@android:color/transparent" 69 android:hint="请输入登录密码(至少为8个字符)" 70 android:inputType="textPassword" 71 android:textColor="@android:color/black" 72 android:textColorHint="#ccc" 73 android:textSize="16sp" /> 74 </LinearLayout> 75 76 <View 77 android:layout_width="match_parent" 78 android:layout_height="1px" 79 android:background="#3000" /> 80 81 <LinearLayout 82 android:layout_width="match_parent" 83 android:layout_height="wrap_content" 84 android:gravity="center_vertical" 85 android:orientation="horizontal" 86 android:paddingBottom="30dp" 87 android:paddingLeft="30dp" 88 android:paddingRight="30dp" 89 android:paddingTop="15dp"> 90 91 <TextView 92 android:layout_width="0dp" 93 android:layout_height="wrap_content" 94 android:layout_weight="1" 95 android:drawableLeft="@drawable/ic_password" /> 96 97 <EditText 98 android:id="@+id/confirm_password" 99 android:layout_width="0dp" 100 android:layout_height="wrap_content" 101 android:layout_weight="5" 102 android:background="@android:color/transparent" 103 android:hint="请确认登录密码(至少为8个字符)" 104 android:inputType="textPassword" 105 android:textColor="@android:color/black" 106 android:textColorHint="#ccc" 107 android:textSize="16sp" /> 108 </LinearLayout> 109 110 111 <Button 112 android:id="@+id/register" 113 android:layout_width="match_parent" 114 android:layout_height="40dp" 115 android:layout_marginLeft="50dp" 116 android:layout_marginRight="50dp" 117 android:layout_marginTop="10dp" 118 android:background="@drawable/btn_bkg_red_rect_round" 119 android:text="注册新账号" 120 android:textColor="@color/colorPrimaryDark" /> 121 122 <TextView 123 android:layout_width="match_parent" 124 android:layout_height="wrap_content" 125 android:layout_marginTop="10dp" 126 android:gravity="center" 127 android:text="注册即表示同意 小熊直播条款" /> 128 </LinearLayout>
【框架的搭建】
1 public class RegisterActivity extends AppCompatActivity { 2 3 private Toolbar mTitlebar; 4 5 private EditText mAccountEdt; 6 private EditText mPasswordEdt; 7 private EditText mConfirmPasswordEt; 8 9 private Button mRegisterBtn; 10 11 @Override 12 protected void onCreate(Bundle savedInstanceState) { 13 super.onCreate(savedInstanceState); 14 setContentView(R.layout.activity_register); 15 16 findAllViews(); 17 setListeners(); 18 setTitleBar(); 19 } 20 21 private void setTitleBar() { 22 mTitlebar.setTitle("注册新用户"); 23 mTitlebar.setTitleTextColor(Color.WHITE); 24 setSupportActionBar(mTitlebar); 25 } 26 27 private void findAllViews() { 28 mTitlebar = (Toolbar) findViewById(R.id.titlebar); 29 30 mAccountEdt = (EditText) findViewById(R.id.account); 31 mPasswordEdt = (EditText) findViewById(R.id.password); 32 mConfirmPasswordEt = (EditText) findViewById(R.id.confirm_password); 33 mRegisterBtn = (Button) findViewById(R.id.register); 34 } 35 36 private void setListeners() { 37 mRegisterBtn.setOnClickListener(new View.OnClickListener() { 38 @Override 39 public void onClick(View v) { 40 //注册 41 register(); 42 } 43 }); 44 }
【修改没有标题的bar】

【注册逻辑的参考】

【源码】
1 private void register() { 2 String accountStr = mAccountEdt.getText().toString(); 3 String passwordStr = mPasswordEdt.getText().toString(); 4 String confirmPswStr = mConfirmPasswordEt.getText().toString(); 5 6 if (TextUtils.isEmpty(accountStr) || 7 TextUtils.isEmpty(passwordStr) || 8 TextUtils.isEmpty(confirmPswStr)) { 9 Toast.makeText(this, "账号或密码不能为空", Toast.LENGTH_SHORT).show(); 10 return; 11 } 12 13 if (!passwordStr.equals(confirmPswStr)) { 14 Toast.makeText(this, "两次密码输入不一致", Toast.LENGTH_SHORT).show(); 15 return; 16 } 17 18 ILiveLoginManager.getInstance().tlsRegister(accountStr, passwordStr, new ILiveCallBack() { 19 @Override 20 public void onSuccess(Object data) { 21 //注册成功 22 Toast.makeText(RegisterActivity.this, "注册成功", Toast.LENGTH_SHORT).show(); 23 //登录一下 24 login(); 25 26 } 27 28 @Override 29 public void onError(String module, int errCode, String errMsg) { 30 //注册失败 31 Toast.makeText(RegisterActivity.this, "注册失败:" + errMsg, Toast.LENGTH_SHORT).show(); 32 33 } 34 }); 35 36 }
2.4 登陆页面到注册页面的跳转

2.5 将登陆页面作为APP的主页面

2.6 将应用程序的页面加入配置清单

2.7 效果


3. 编辑用户信息的界面的实现

3.1 个人信息编辑界面布局
【说明】登陆成功之后应该可以让用户进入到编辑个人信息的界面

【建立用户个人信息的界面】


【布局】将布局简化抽取分为三部分

【第二部分的布局的实现】自定义控件,以中间的第二部分的布局为基类进行建立;
1 package imooc.com.bearlive.editprofile; 2 3 import android.content.Context; 4 import android.util.AttributeSet; 5 import android.view.LayoutInflater; 6 import android.widget.ImageView; 7 import android.widget.LinearLayout; 8 import android.widget.TextView; 9 10 import imooc.com.bearlive.R; 11 12 /** 13 * Created by Administrator on 2017/4/2. 14 */ 15 16 public class ProfileEdit extends LinearLayout { //继承与LinearLayout线性布局 17 18 private ImageView mIconView; 19 private TextView mKeyView; 20 private TextView mValueView; 21 private ImageView mRightArrowView; 22 23 public ProfileEdit(Context context) { 24 super(context); 25 init(); 26 } 27 28 public ProfileEdit(Context context, AttributeSet attrs) { 29 super(context, attrs); 30 init(); 31 } 32 33 public ProfileEdit(Context context, AttributeSet attrs, int defStyleAttr) { 34 super(context, attrs, defStyleAttr); 35 init(); 36 } 37 38 private void init() { //将布局转为View; 39 LayoutInflater.from(getContext()).inflate(R.layout.view_profile_edit, this 40 , true); 41 findAllViews(); 42 } 43 44 private void findAllViews() { 45 mIconView = (ImageView) findViewById(R.id.profile_icon); 46 mKeyView = (TextView) findViewById(R.id.profile_key); 47 mValueView = (TextView) findViewById(R.id.profile_value); 48 mRightArrowView = (ImageView) findViewById(R.id.right_arrow); 49 } 50 //设置每个横条的信息的内容 51 public void set(int iconResId, String key, String value) { 52 mIconView.setImageResource(iconResId); 53 mKeyView.setText(key); 54 mValueView.setText(value); 55 } 56 57 public void updateValue(String value) { 58 mValueView.setText(value); 59 } 60 61 public String getValue() { 62 return mValueView.getText().toString(); 63 } 64 //将箭头的隐藏掉,作为个人信息编辑也的下半部分的不可编辑的部分; 65 protected void disableEdit() { 66 mRightArrowView.setVisibility(GONE); 67 } 68 }
【自定义的布局】layout/view_profile_edit.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:gravity="center_vertical" 6 android:minHeight="50dp" 7 android:orientation="horizontal" 8 android:padding="5dp"> 9 10 <ImageView 11 android:id="@+id/profile_icon" 12 android:layout_width="wrap_content" 13 android:layout_height="wrap_content" /> 14 15 <TextView 16 android:id="@+id/profile_key" 17 android:layout_width="wrap_content" 18 android:layout_height="wrap_content" 19 android:layout_marginLeft="5dp" 20 android:textColor="#333" /> 21 22 <TextView 23 android:id="@+id/profile_value" 24 android:layout_width="0dp" 25 android:layout_height="wrap_content" 26 android:layout_weight="1" 27 android:maxWidth="300dp" 28 android:gravity="right" 29 android:textColor="#999" /> 30 31 <ImageView 32 android:id="@+id/right_arrow" 33 android:layout_width="wrap_content" 34 android:layout_height="wrap_content" 35 android:src="@drawable/ic_right_arrow" /> 36 </LinearLayout>


【第三部分布局的实现】在第二部分的基础上隐藏掉箭头

【源码】imooc.com.bearlive.editprofile.ProfileTextView 自定义控件,隐藏箭头;
1 package imooc.com.bearlive.editprofile; 2 3 import android.content.Context; 4 import android.util.AttributeSet; 5 6 /** 7 * Created by Administrator on 2017/4/2. 8 */ 9 10 public class ProfileTextView extends ProfileEdit { 11 public ProfileTextView(Context context) { 12 super(context); 13 disableEdit(); //调用父类的方法 14 } 15 16 public ProfileTextView(Context context, AttributeSet attrs) { 17 super(context, attrs); 18 disableEdit(); 19 } 20 public ProfileTextView(Context context, AttributeSet attrs, int defStyleAttr) { 21 super(context, attrs, defStyleAttr); 22 disableEdit(); 23 } 24 }
【父类中的方法】

【最终布局的替换】

【源码】
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:id="@+id/activity_edit_profile" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent" 6 android:orientation="vertical"> 7 8 <android.support.v7.widget.Toolbar 9 android:id="@+id/title_bar" 10 android:layout_width="match_parent" 11 android:layout_height="?attr/actionBarSize" 12 android:background="@color/colorPrimaryDark" /> 13 14 <ScrollView 15 android:layout_width="match_parent" 16 android:layout_height="wrap_content"> 17 18 <LinearLayout 19 android:layout_width="match_parent" 20 android:layout_height="wrap_content" 21 android:orientation="vertical"> 22 23 <LinearLayout 24 android:id="@+id/avatar" 25 android:layout_width="match_parent" 26 android:layout_height="wrap_content" 27 android:gravity="center_vertical" 28 android:minHeight="50dp" 29 android:orientation="horizontal" 30 android:padding="5dp"> 31 32 <ImageView 33 android:layout_width="wrap_content" 34 android:layout_height="wrap_content" 35 android:src="@drawable/ic_info_avatar" /> 36 37 <TextView 38 android:layout_width="0dp" 39 android:layout_height="wrap_content" 40 android:layout_marginLeft="5dp" 41 android:layout_weight="1" 42 android:text="头像" 43 android:textColor="#333" /> 44 45 <ImageView 46 android:id="@+id/avatar_img" 47 android:layout_width="45dp" 48 android:layout_height="45dp" 49 android:layout_marginLeft="5dp" /> 50 </LinearLayout> 51 52 <imooc.com.bearlive.editprofile.ProfileEdit 53 android:id="@+id/nick_name" 54 android:layout_width="match_parent" 55 android:layout_height="wrap_content" /> 56 57 <imooc.com.bearlive.editprofile.ProfileEdit 58 android:id="@+id/gender" 59 android:layout_width="match_parent" 60 android:layout_height="wrap_content" /> 61 62 <imooc.com.bearlive.editprofile.ProfileEdit 63 android:id="@+id/sign" 64 android:layout_width="match_parent" 65 android:layout_height="wrap_content" /> 66 67 <imooc.com.bearlive.editprofile.ProfileEdit 68 android:id="@+id/renzheng" 69 android:layout_width="match_parent" 70 android:layout_height="wrap_content" /> 71 72 <imooc.com.bearlive.editprofile.ProfileEdit 73 android:id="@+id/location" 74 android:layout_width="match_parent" 75 android:layout_height="wrap_content" /> 76 77 <View 78 android:layout_width="match_parent" 79 android:layout_height="1px" 80 android:background="#333" /> 81 82 <imooc.com.bearlive.editprofile.ProfileTextView 83 android:id="@+id/id" 84 android:layout_width="match_parent" 85 android:layout_height="wrap_content" /> 86 87 <imooc.com.bearlive.editprofile.ProfileTextView 88 android:id="@+id/level" 89 android:layout_width="match_parent" 90 android:layout_height="wrap_content" /> 91 92 <imooc.com.bearlive.editprofile.ProfileTextView 93 android:id="@+id/get_nums" 94 android:layout_width="match_parent" 95 android:layout_height="wrap_content" /> 96 97 <imooc.com.bearlive.editprofile.ProfileTextView 98 android:id="@+id/send_nums" 99 android:layout_width="match_parent" 100 android:layout_height="wrap_content" /> 101 102 <View 103 android:layout_width="match_parent" 104 android:layout_height="1px" 105 android:background="#333" /> 106 107 <Button 108 android:id="@+id/complete" 109 android:layout_width="match_parent" 110 android:layout_height="wrap_content" 111 android:layout_margin="20dp" 112 android:background="@drawable/btn_bkg_blue_rect_round" 113 android:text="完成" 114 android:textColor="@android:color/holo_blue_dark" /> 115 </LinearLayout> 116 </ScrollView> 117 </LinearLayout>

3.2 编辑个人信息代码的框架
【EditProfileActivity.java】个人信息列表的逻辑框架
1 package imooc.com.bearlive.editprofile; 2 3 import android.app.Activity; 4 import android.content.Intent; 5 import android.graphics.Color; 6 import android.os.Bundle; 7 import android.support.annotation.Nullable; 8 import android.support.v4.app.Fragment; 9 import android.support.v7.app.AppCompatActivity; 10 import android.support.v7.widget.Toolbar; 11 import android.text.TextUtils; 12 import android.view.LayoutInflater; 13 import android.view.View; 14 import android.view.ViewGroup; 15 import android.widget.Button; 16 import android.widget.ImageView; 17 import android.widget.Toast; 18 19 import com.tencent.TIMCallBack; 20 import com.tencent.TIMFriendGenderType; 21 import com.tencent.TIMFriendshipManager; 22 import com.tencent.TIMUserProfile; 23 import com.tencent.TIMValueCallBack; 24 25 import java.util.Map; 26 27 import imooc.com.bearlive.R; 28 import imooc.com.bearlive.main.MainActivity; 29 import imooc.com.bearlive.utils.ImgUtils; 30 import imooc.com.bearlive.utils.PicChooserHelper; 31 32 /** 33 * Created by Administrator. 34 */ 35 36 public class EditProfileActivity extends AppCompatActivity { 37 38 39 private Toolbar mTitlebar; 40 private View mAvatarView; 41 private ImageView mAvatarImg; 42 private ProfileEdit mNickNameEdt; 43 private ProfileEdit mGenderEdt; 44 private ProfileEdit mSignEdt; 45 private ProfileEdit mRenzhengEdt; 46 private ProfileEdit mLocationEdt; 47 48 private ProfileTextView mIdView; 49 private ProfileTextView mLevelView; 50 private ProfileTextView mGetNumsView; 51 private ProfileTextView mSendNumsView; 52 53 private Button mCompleteBtn; 54 55 56 57 58 @Nullable 59 @Override 60 public void onCreate(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 61 View mainView = inflater.inflate(R.layout.fragment_edit_profile, container, false); 62 findAllViews(mainView); 63 setListeners(); 64 setTitleBar(); 65 setIconKey();//设置字段和icon 66 67 } 68 69 private void setIconKey() { 70 mNickNameEdt.set(R.drawable.ic_info_nickname, "昵称"); 71 mGenderEdt.set(R.drawable.ic_info_gender, "性别"); 72 mSignEdt.set(R.drawable.ic_info_sign, "签名"); 73 mRenzhengEdt.set(R.drawable.ic_info_renzhen, "认证", "未知"); 74 mLocationEdt.set(R.drawable.ic_info_location, "地区"); 75 mIdView.set(R.drawable.ic_info_id, "ID"); 76 mLevelView.set(R.drawable.ic_info_level, "等级"); 77 mGetNumsView.set(R.drawable.ic_info_get, "获得票数"); 78 mSendNumsView.set(R.drawable.ic_info_send, "送出票数"); 79 } 80 81 private void findAllViews(View view) { 82 mTitlebar = (Toolbar) view.findViewById(R.id.title_bar); 83 84 mAvatarView = view.findViewById(R.id.avatar); 85 mAvatarImg = (ImageView) view.findViewById(R.id.avatar_img); 86 mNickNameEdt = (ProfileEdit) view.findViewById(R.id.nick_name); 87 mGenderEdt = (ProfileEdit) view.findViewById(R.id.gender); 88 mSignEdt = (ProfileEdit) view.findViewById(R.id.sign); 89 mRenzhengEdt = (ProfileEdit) view.findViewById(R.id.renzheng); 90 mLocationEdt = (ProfileEdit) view.findViewById(R.id.location); 91 92 mIdView = (ProfileTextView) view.findViewById(R.id.id); 93 mLevelView = (ProfileTextView) view.findViewById(R.id.level); 94 mGetNumsView = (ProfileTextView) view.findViewById(R.id.get_nums); 95 mSendNumsView = (ProfileTextView) view.findViewById(R.id.send_nums); 96 97 mCompleteBtn = (Button) view.findViewById(R.id.complete); 98 } 99 100 private void setListeners() { 101 mAvatarView.setOnClickListener(clickListener); 102 mNickNameEdt.setOnClickListener(clickListener); 103 mGenderEdt.setOnClickListener(clickListener); 104 mSignEdt.setOnClickListener(clickListener); 105 mRenzhengEdt.setOnClickListener(clickListener); 106 mLocationEdt.setOnClickListener(clickListener); 107 mCompleteBtn.setOnClickListener(clickListener); 108 } 109 110 private void setTitleBar() { 111 mTitlebar.setTitle("编辑个人信息"); 112 mTitlebar.setTitleTextColor(Color.WHITE); 113 114 setSupportActionBar(mTitlebar); 115 116 } 117 118 private View.OnClickListener clickListener = new View.OnClickListener() { 119 @Override 120 public void onClick(View view) { 121 122 } 123 }; 124 125
3.3 获取个人信息
【说明】获取个人的地方有两处:【1】注册的时候的信息;【2】登陆的时候存在信息;
【注意】在获取票数和送出票的字段属于是自己增加的,需要在腾讯云官网的TLS后台进行申请添加;

【字段信息的汇总】imooc.com.bearlive.editprofile.CustomProfile
1 package imooc.com.bearlive.editprofile; 2 3 import com.tencent.TIMFriendshipManager; 4 5 /** 6 * Created by Administrator on 2017/4/2. 7 * 用户信息字段 8 */ 9 public class CustomProfile { 10 //自定义字段--我们自己添加的字段 11 private static final String PREFIX = "Tag_Profile_Custom_"; 12 public static final String CUSTOM_RENZHENG = PREFIX + "renzhen"; 13 public static final String CUSTOM_LEVEL = PREFIX + "level"; 14 public static final String CUSTOM_GET = PREFIX + "getNums"; 15 public static final String CUSTOM_SEND = PREFIX + "sendNums"; 16 17 //腾讯基础字段 18 public static final long allBaseInfo = 19 TIMFriendshipManager.TIM_PROFILE_FLAG_BIRTHDAY | 20 TIMFriendshipManager.TIM_PROFILE_FLAG_FACE_URL | 21 TIMFriendshipManager.TIM_PROFILE_FLAG_GENDER | 22 TIMFriendshipManager.TIM_PROFILE_FLAG_LANGUAGE | 23 TIMFriendshipManager.TIM_PROFILE_FLAG_LOCATION | 24 TIMFriendshipManager.TIM_PROFILE_FLAG_NICK | 25 TIMFriendshipManager.TIM_PROFILE_FLAG_SELF_SIGNATURE | 26 TIMFriendshipManager.TIM_PROFILE_FLAG_REMARK | 27 TIMFriendshipManager.TIM_PROFILE_FLAG_GROUP; 28 }
【字段信息的初始化】

【登陆之后获取个人信息的字段】




3.4 设置获取的个人信息
【说明】注意本身自带的字段和新增加的字段的获取的不同;


【ImgUtils的实现】使用到了glide开源库
【新建包和类】

【增加第三方的开源库】

【使用glide加载】imooc.com.bearlive.utils.ImgUtils.java
1 package imooc.com.bearlive.utils; 2 3 import android.widget.ImageView; 4 5 import com.bumptech.glide.Glide; 6 7 import imooc.com.bearlive.BearApplication; 8 import jp.wasabeef.glide.transformations.CropCircleTransformation; 9 10 /** 11 * Created by Administrator on 2017/4/3. 12 */ 13 14 public class ImgUtils { 15 16 public static void load(String url, ImageView targetView) { 17 Glide.with(BearApplication.getContext()) 18 .load(url) 19 .into(targetView); 20 } 21 22 public static void load(int resId, ImageView targetView) { 23 Glide.with(BearApplication.getContext()) 24 .load(resId) 25 .into(targetView); 26 } 27 28 public static void loadRound(String url, ImageView targetView) { 29 Glide.with(BearApplication.getContext()) 30 .load(url) 31 .bitmapTransform(new CropCircleTransformation(BearApplication.getContext())) 32 .into(targetView); 33 } 34 35 public static void loadRound(int resId, ImageView targetView) { 36 Glide.with(BearApplication.getContext()) 37 .load(resId) 38 .bitmapTransform(new CropCircleTransformation(BearApplication.getContext())) 39 .into(targetView); 40 } 41 }
【增加容错】


3.5 个人信息的修改
【思路】点击某一项之后弹出该项的对话框,然后用户输入新的设置信息;
然后更新该信息的值,然后刷新界面的信息;
更新之后提交到服务器,服务器然后刷新界面;
【实例】以签名为例,其他的更新类似;


【对话的显示的抽取】自定义控件;imooc.com.bearlive.editprofile.EditStrProfileDialog.java;
1 package imooc.com.bearlive.editprofile; 2 3 import android.app.Activity; 4 import android.view.LayoutInflater; 5 import android.view.View; 6 import android.view.WindowManager; 7 import android.widget.EditText; 8 import android.widget.TextView; 9 10 import imooc.com.bearlive.R; 11 import imooc.com.bearlive.widget.TransParentDialog; 12 13 /** 14 * Created by Administrator on 2017/4/3. 15 */ 16 17 public class EditStrProfileDialog extends TransParentDialog { //父类:主要显示透明的效果 18 private TextView titleView; 19 private EditText contentView; 20 21 public EditStrProfileDialog(Activity activity) { 22 super(activity); 23 View mainView = LayoutInflater.from(activity).inflate(R.layout.dialog_edit_str_profile, null, false); 24 titleView = (TextView) mainView.findViewById(R.id.title); 25 contentView = (EditText) mainView.findViewById(R.id.content); 26 setContentView(mainView); 27 28 setWidthAndHeight(activity.getWindow().getDecorView().getWidth() * 80 / 100, WindowManager.LayoutParams.WRAP_CONTENT); 29 mainView.findViewById(R.id.ok).setOnClickListener(new View.OnClickListener() { //做监听 30 @Override 31 public void onClick(View v) { 32 33 String content = contentView.getText().toString(); 34 if (onOKListener != null) { 35 onOKListener.onOk(mTitle, content);//回调onOk方法 36 } 37 38 hide(); 39 } 40 }); 41 } 42 43 private String mTitle; 44 45 public void show(String title, int resId, String defaultContent) { 46 mTitle = title; 47 titleView.setText("请输入" + title); 48 49 contentView.setCompoundDrawablesWithIntrinsicBounds(resId, 0, 0, 0); 50 contentView.setText(defaultContent); 51 show(); 52 } 53 54 private OnOKListener onOKListener; 55 56 public void setOnOKListener(OnOKListener l) { 57 onOKListener = l; 58 } 59 60 public interface OnOKListener { 61 void onOk(String title, String content); 62 } 63 }
【布局】dialog_edit_str_profile.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:background="@drawable/dialog_white_round_bkg" 6 android:orientation="vertical"> 7 8 <TextView 9 android:id="@+id/title" 10 style="@style/Base.TextAppearance.AppCompat.Title" 11 android:layout_width="match_parent" 12 android:layout_height="wrap_content" 13 android:layout_margin="20dp" 14 android:gravity="center" /> 15 16 <EditText 17 android:id="@+id/content" 18 android:layout_width="match_parent" 19 android:layout_height="wrap_content" 20 android:layout_marginTop="10dp" 21 android:background="@null" 22 android:drawableLeft="@drawable/ic_account" 23 android:drawablePadding="10dp" 24 android:gravity="center_vertical" 25 android:maxLength="32" 26 android:maxLines="1" 27 android:paddingLeft="10dp" 28 android:paddingRight="20dp" 29 android:singleLine="true" 30 android:textColor="@android:color/black" 31 android:textSize="20sp" /> 32 33 <TextView 34 android:id="@+id/ok" 35 style="@style/Widget.AppCompat.Button.Borderless" 36 android:layout_width="wrap_content" 37 android:layout_height="wrap_content" 38 android:layout_gravity="right" 39 android:layout_margin="10dp" 40 android:text="确定" 41 android:textSize="18sp" /> 42 </LinearLayout>
【布局的效果】

【透明效果-布局父类】
1 package imooc.com.bearlive.widget; 2 3 import android.app.Activity; 4 import android.app.Dialog; 5 import android.view.View; 6 import android.view.Window; 7 import android.view.WindowManager; 8 9 import imooc.com.bearlive.R; 10 11 /** 12 * Created by Administrator on 2017/4/3. 13 */ 14 15 public class TransParentDialog { 16 protected Activity activity; 17 protected Dialog dialog; 18 19 public TransParentDialog(Activity activity) { 20 this.activity = activity; 21 dialog = new Dialog(activity, R.style.dialog); //定义了样式 22 } 23 24 public void setContentView(View view) { 25 dialog.setContentView(view); 26 } 27 28 public void setWidthAndHeight(int width, int height) { 29 Window win = dialog.getWindow(); 30 WindowManager.LayoutParams params = win.getAttributes(); 31 if (params != null) { 32 params.width = width;//设置宽度 33 params.height = height;//设置高度 34 win.setAttributes(params); 35 } 36 } 37 38 public void show() { 39 dialog.show(); 40 } 41 42 public void hide() { 43 dialog.hide(); 44 } 45 }





3.6 个人信息修改之头像修改
3.6.1 从相册中选择图片
【头像选择对话框】点击头像头像后,会出现对话框,在屏幕的下方;需要选择图片;

【布局】存在两个TextView,一个ImageView;一个是相册选择图片,一个相机拍摄一张图片,一个取消;
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="wrap_content" 5 android:layout_gravity="bottom" 6 android:background="@android:color/white" 7 android:orientation="vertical" 8 android:padding="30dp"> 9 10 <TextView 11 android:id="@+id/pic_camera" 12 android:layout_width="fill_parent" 13 android:layout_height="40dp" 14 android:layout_gravity="center" 15 android:background="@drawable/btn_bkg_blue_rect_round" 16 android:gravity="center" 17 android:text="拍照" 18 android:textColor="@android:color/holo_blue_dark" /> 19 20 <TextView 21 android:id="@+id/pic_album" 22 android:layout_width="fill_parent" 23 android:layout_height="40dp" 24 android:layout_marginTop="10dp" 25 android:layout_gravity="center" 26 android:background="@drawable/btn_bkg_red_rect_round" 27 android:gravity="center" 28 android:text="相册" 29 android:textColor="@color/colorPrimaryDark" /> 30 31 32 <ImageView 33 android:id="@+id/pic_cancel" 34 android:layout_width="wrap_content" 35 android:layout_height="wrap_content" 36 android:layout_gravity="center" 37 android:layout_marginTop="10dp" 38 android:background="@drawable/ic_pic_choose_close" /> 39 </LinearLayout>

【源码】imooc.com.bearlive.widget.PicChooseDialog
1 package imooc.com.bearlive.widget; 2 3 import android.app.Activity; 4 import android.view.Gravity; 5 import android.view.LayoutInflater; 6 import android.view.View; 7 import android.view.Window; 8 import android.view.WindowManager; 9 10 import imooc.com.bearlive.R; 11 12 /** 13 * Created by Administrator on 2017/4/3. 14 */ 15 16 public class PicChooseDialog extends TransParentDialog { 17 public PicChooseDialog(Activity activity) { 18 super(activity); 19 View view = LayoutInflater.from(activity).inflate(R.layout.dialog_pic_choose, null, false); //找到布局 20 setContentView(view); 21 setWidthAndHeight(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT); 22 23 24 View camera = view.findViewById(R.id.pic_camera); 25 View picLib = view.findViewById(R.id.pic_album); 26 View cancel = view.findViewById(R.id.pic_cancel); 27 camera.setOnClickListener(new View.OnClickListener() { //设置监听 28 @Override 29 public void onClick(View view) { 30 hide(); 31 if (onDialogClickListener != null) { 32 onDialogClickListener.onCamera(); 33 } 34 } 35 }); 36 37 picLib.setOnClickListener(new View.OnClickListener() { //设置监听 38 @Override 39 public void onClick(View view) { 40 41 hide(); 42 if (onDialogClickListener != null) { 43 onDialogClickListener.onAlbum(); 44 } 45 } 46 }); 47 cancel.setOnClickListener(new View.OnClickListener() { //设置监听 48 @Override 49 public void onClick(View v) { 50 hide(); 51 } 52 }); 53 } 54 55 private OnDialogClickListener onDialogClickListener; 56 57 public void setOnDialogClickListener(OnDialogClickListener l) { 58 onDialogClickListener = l; 59 } 60 61 public interface OnDialogClickListener { //作为接口让子类实现 62 void onCamera(); 63 64 void onAlbum(); 65 } 66 67 @Override 68 public void show() { //对话框在底部显示 69 Window window = dialog.getWindow(); 70 WindowManager.LayoutParams lp = window.getAttributes(); 71 lp.gravity = Gravity.BOTTOM; 72 dialog.getWindow().setAttributes(lp); 73 74 super.show(); 75 } 76 77 }
【单写一个工具类,用来专门的选择图片】除了在头像的选择使用图片选择,在直播时的封面的图片的选择也需要使用此类;
【拿到相册的数据】

【工具类】【相册数据的返回】

【图片的剪裁】

【剪裁图片的地址的生成】

【跳转页面】开始剪裁

【个人信息页面设置】【取出相册的数据并使用】编辑个人数据页面新建工具类;


3.6.2 【将数据上传到七牛云】

【说明】仔细阅读开发者中心的androidSDK文档,写明了如何配置android,存在安全机制和生成上传凭证;

【使用该算法则不需要使用服务器进行验证了】

【配置七牛的加载库】

【七牛工具类】
1 package imooc.com.bearlive.utils; 2 import android.util.Log; 3 4 import com.qiniu.android.common.Zone; 5 import com.qiniu.android.http.ResponseInfo; 6 import com.qiniu.android.storage.Configuration; 7 import com.qiniu.android.storage.UpCompletionHandler; 8 import com.qiniu.android.storage.UploadManager; 9 import com.qiniu.android.utils.UrlSafeBase64; 10 11 import org.json.JSONObject; 12 13 import javax.crypto.Mac; 14 import javax.crypto.SecretKey; 15 import javax.crypto.spec.SecretKeySpec; 16 /** 17 * Created by Administrator on 2017/4/3. 18 */ 19 20 public class QnUploadHelper { 21 private static final String TAG = QnUploadHelper.class.getSimpleName(); 22 //七牛后台的key--与个人的信息的账户有关系 23 private static String AccessKey; 24 //七牛后台的secret-与个人的信息的账户有关系 25 private static String SecretKey; 26 27 private static String Domain; //服务器所属的区域:华南、华北等等; 28 private static String BucketName; //存储区域所在的名字 29 30 private static final String MAC_NAME = "HmacSHA1"; 31 private static final String ENCODING = "UTF-8"; 32 33 private static Configuration configuration; //配置 34 35 private static long delayTimes = 3029414400l; //有效时间 36 37 public static void init(String accessKey, String secretKey,String domain, String bucketName) { 38 AccessKey = accessKey; 39 SecretKey = secretKey; 40 Domain = domain; 41 BucketName = bucketName; 42 43 configuration = new Configuration.Builder().build(); //调用默认的Configuraton 44 } 45 46 /** 47 * 上传 48 * 49 // * @param bucketName bucketName的名字 50 * @param path 上传文件的路径地址 51 * keys:上传的文件的名字; 52 * callBack:上传之后的回调方法 53 */ 54 public static void uploadPic(final String path, final String keys, final UploadCallBack callBack) { 55 try { 56 //*************构造touken开始***官网存在的算法******************** 57 // 1:第一种方式 构造上传策略 58 JSONObject _json = new JSONObject(); 59 _json.put("deadline", delayTimes); 60 _json.put("scope", BucketName); 61 String _encodedPutPolicy = UrlSafeBase64.encodeToString(_json 62 .toString().getBytes()); 63 byte[] _sign = HmacSHA1Encrypt(_encodedPutPolicy, SecretKey); 64 String _encodedSign = UrlSafeBase64.encodeToString(_sign); 65 final String _uploadToken = AccessKey + ':' + _encodedSign + ':' 66 + _encodedPutPolicy; 67 //*************构造token结束**************************************** 68 69 //UploadManager七牛自己的类,将configuration配置传递; 70 UploadManager uploadManager = new UploadManager(configuration); 71 //将路径:path,keys,token 作为参数进行上传 72 uploadManager.put(path, keys, _uploadToken, 73 new UpCompletionHandler() { 74 @Override 75 public void complete(String key, ResponseInfo info, 76 JSONObject response) { 77 Log.d(TAG,"response = " + response); 78 //根据info的信息,判断是否上传成功; 79 if (info.isOK()) { 80 //如果上传成功,则拼接服务器所在的地区的名字+key; 81 String picUrl = Domain + keys; 82 //调用我们自己的定义的callBack 方法; //见116行 83 callBack.success(picUrl); 84 } else 85 callBack.fail(key, info); 86 } 87 }, null); 88 } catch (Exception e) { 89 e.printStackTrace(); 90 } 91 } 92 93 94 /** 95 * 使用 HMAC-SHA1 签名方法对对encryptText进行签名 96 * 97 * @param encryptText 被签名的字符串 98 * @param encryptKey 密钥 99 * @return 100 * @throws Exception 101 */ 102 public static byte[] HmacSHA1Encrypt(String encryptText, String encryptKey) 103 throws Exception { 104 byte[] data = encryptKey.getBytes(ENCODING); 105 // 根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称 106 SecretKey secretKey = new SecretKeySpec(data, MAC_NAME); 107 // 生成一个指定 Mac 算法 的 Mac 对象 108 Mac mac = Mac.getInstance(MAC_NAME); 109 // 用给定密钥初始化 Mac 对象 110 mac.init(secretKey); 111 byte[] text = encryptText.getBytes(ENCODING); 112 // 完成 Mac 操作 113 return mac.doFinal(text); 114 } 115 116 public interface UploadCallBack { 117 //成功的话将成功请求的地址返回; 118 void success(String url); 119 //失败的话则返回info信息 120 void fail(String key, ResponseInfo info); 121 } 122 123 }
【工具类的初始化】


【AK和SK的获取】



【数据上传】





【上传的回调的完成】


【效果】更新 失败;

【BUG】修改-原因:上传云的名称拼接错误;




【注意】

3.6.2 从相机拍摄照片
【说明】流程与从相册选择照片是大同小异的,具体的细节不太一致;

【创建照片的url】


【对url兼容性的处理】



【开始剪裁】

【说明】剪裁之后上传到7牛云中,然后更新页面;
4. APP主界面的实现

4.1 增加主界面的三个Tab的切换-使用fragment
【布局】
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:tools="http://schemas.android.com/tools" 4 android:id="@+id/activity_main" 5 android:layout_width="match_parent" 6 android:layout_height="match_parent" 7 android:orientation="vertical" 8 tools:context="imooc.com.bearlive.main.MainActivity"> 9 10 <FrameLayout 11 android:id="@+id/fragment_container" 12 android:layout_width="match_parent" 13 android:layout_height="0dp" 14 android:layout_weight="1" /> //主界面中的fragment的内容展示 15 16 <android.support.v4.app.FragmentTabHost //底部的三个切换按钮 17 android:id="@+id/fragment_tabhost" 18 android:layout_width="match_parent" 19 android:layout_height="wrap_content" /> 20 </LinearLayout>

【设置TabHost】

【创建列表的按钮】-中间的参数缺少fragment.class


【创建个人信息修改的fragment】

【TabHost中添加按钮】【说明】直接创建直播的按钮是不需要fragment,因此此处写为空;

4.2 指示器的编写
【布局】

【源码】
1 package imooc.com.bearlive.main; 2 3 import android.content.Intent; 4 import android.os.Bundle; 5 import android.support.v4.app.FragmentTabHost; 6 import android.support.v7.app.AppCompatActivity; 7 import android.view.LayoutInflater; 8 import android.view.View; 9 import android.widget.FrameLayout; 10 import android.widget.ImageView; 11 import android.widget.TabHost; 12 13 import imooc.com.bearlive.R; 14 import imooc.com.bearlive.createroom.CreateLiveActivity; 15 import imooc.com.bearlive.editprofile.EditProfileFragment; 16 import imooc.com.bearlive.livelist.LiveListFragment; 17 18 public class MainActivity extends AppCompatActivity { 19 20 private FrameLayout mContainer; 21 private FragmentTabHost mTabHost; 22 23 @Override 24 protected void onCreate(Bundle savedInstanceState) { 25 super.onCreate(savedInstanceState); 26 setContentView(R.layout.activity_main); 27 28 findAllViews(); 29 setTabs(); 30 } 31 32 private void setTabs() { 33 mTabHost.setup(this, getSupportFragmentManager(), R.id.fragment_container); 34 35 //添加fragment. 36 37 { //见56行 38 TabHost.TabSpec profileTab = mTabHost.newTabSpec("livelist").setIndicator(getIndicator(R.drawable.tab_livelist)); 39 mTabHost.addTab(profileTab, LiveListFragment.class, null); 40 mTabHost.getTabWidget().setDividerDrawable(null); 41 } 42 43 { 44 TabHost.TabSpec profileTab = mTabHost.newTabSpec("createlive").setIndicator(getIndicator(R.drawable.tab_publish_live)); 45 mTabHost.addTab(profileTab, null, null); 46 mTabHost.getTabWidget().setDividerDrawable(null); 47 } 48 49 { 50 TabHost.TabSpec profileTab = mTabHost.newTabSpec("profile").setIndicator(getIndicator(R.drawable.tab_profile)); 51 mTabHost.addTab(profileTab, EditProfileFragment.class, null); 52 mTabHost.getTabWidget().setDividerDrawable(null); 53 } 54 } 55 //指示器的设置 56 private View getIndicator(int resId) { 57 View tabView = LayoutInflater.from(this).inflate(R.layout.view_indicator, null); 58 ImageView tabImg = (ImageView) tabView.findViewById(R.id.tab_icon); 59 tabImg.setImageResource(resId); 60 return tabView; 61 } 62 63 private void findAllViews() { 64 mContainer = (FrameLayout) findViewById(R.id.fragment_container); 65 mTabHost = (FragmentTabHost) findViewById(R.id.fragment_tabhost); 66 } 67 }
4.3 主页面的逻辑实现
【说明】判断是否是第一次登陆APP,如果是则跳转到个人信息设置界面,如果不是则跳转到直播的界面;
【逻辑判断】

【第一次登陆的标记的保存】


【崩溃问题的解决】


【处理】

4.4 profile个人信息的页面的fragment的改造
【代码的拷贝】将imooc.com.bearlive.editprofile.EditProfileActivity.java中的代码拷贝到imooc.com.bearlive.editprofile.EditProfileFragment.java中;

【修改布局文件】

【源码中的改造】








【布局文件的改造】

【原来的Activiyt的修改】


【BUG】点击头像之后进入到图册中没有弹出crop剪裁的对话框;

【原因】Activity源码中已经换为了fragment,此处还是使用的Activity开启页面;


【修改】



【效果】到此处的时候可以直接更换头像了;
4.7 个人信息完成按钮的事件的处理

5. 发起直播页面的开发

5.1 布局
【直播类的布局】

【源码】layout/activity_create_room.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:id="@+id/activity_live_prepare" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent"> 6 7 <android.support.v7.widget.Toolbar 8 android:id="@+id/titlebar" 9 android:layout_width="match_parent" 10 android:layout_height="?attr/actionBarSize" 11 android:background="@color/colorPrimaryDark" /> 12 13 <LinearLayout 14 android:layout_width="match_parent" 15 android:layout_height="wrap_content" 16 android:layout_below="@id/titlebar" 17 android:orientation="vertical"> 18 19 <FrameLayout 20 android:id="@+id/set_cover" 21 android:layout_width="match_parent" 22 android:layout_height="wrap_content"> 23 24 <ImageView 25 android:id="@+id/cover" 26 android:layout_width="match_parent" 27 android:layout_height="200dp" 28 android:background="@drawable/default_cover" 29 android:scaleType="fitXY" /> 30 31 <TextView 32 android:id="@+id/tv_pic_tip" 33 android:layout_width="match_parent" 34 android:layout_height="wrap_content" 35 android:layout_gravity="center" 36 android:drawablePadding="5dp" 37 android:drawableTop="@drawable/ic_tip_image" 38 android:gravity="center" 39 android:text="设置直播封面" 40 android:textColor="#ccc" 41 android:textSize="16sp" /> 42 </FrameLayout> 43 44 <LinearLayout 45 android:layout_width="match_parent" 46 android:layout_height="wrap_content" 47 android:gravity="center_vertical" 48 android:orientation="horizontal"> 49 50 <TextView 51 android:layout_width="0dp" 52 android:layout_weight="1" 53 android:layout_height="wrap_content" 54 android:layout_margin="10dp" 55 android:text="标题" 56 android:textSize="18sp" /> 57 58 <EditText 59 android:id="@+id/title" 60 android:layout_width="0dp" 61 android:layout_weight="4" 62 android:layout_height="wrap_content" 63 android:background="@null" 64 android:hint="请输入直播的标题" 65 android:lines="1" 66 android:maxLength="32" 67 android:padding="10dp" 68 android:textSize="20sp" /> 69 </LinearLayout> 70 71 <LinearLayout 72 android:layout_width="match_parent" 73 android:layout_height="wrap_content" 74 android:gravity="center_vertical" 75 android:orientation="horizontal"> 76 77 <TextView 78 android:layout_width="0dp" 79 android:layout_weight="1" 80 android:layout_height="wrap_content" 81 android:layout_margin="10dp" 82 android:text="房间号" 83 android:textSize="18sp" /> 84 85 <TextView 86 android:id="@+id/room_no" 87 android:layout_width="0dp" 88 android:layout_weight="4" 89 android:layout_height="wrap_content" 90 android:lines="1" 91 android:maxLength="32" 92 android:padding="10dp" 93 android:textSize="20sp" /> 94 </LinearLayout> 95 96 97 </LinearLayout> 98 99 <TextView 100 android:id="@+id/create" 101 android:layout_width="fill_parent" 102 android:layout_height="40dp" 103 android:layout_alignParentBottom="true" 104 android:layout_margin="10dp" 105 android:background="@drawable/btn_bkg_red_rect_round" 106 android:gravity="center" 107 android:onClick="onClick" 108 android:text="开始直播" 109 android:textColor="@color/colorPrimaryDark" 110 android:textSize="18sp" /> 111 </RelativeLayout>

5.2 封面的添加



【说明】使用Activity加载图片,因此需要使用ActivityResult();

【图片的形状的改变】封面加载的图片是长方形的,而头像的图片是正方形的;

[增加图形的枚举分类]

[增加长方形的剪裁]


[文件保存的命名的区分]


【根据分类进行设置】



【图像分装类对图像的夹杂处理】


【进入到创建直播的界面】



浙公网安备 33010602011771号