1.家庭列表

2.发帖页面
This commit is contained in:
BA7LZD 2020-06-06 18:27:27 +08:00
parent 449e60c7bd
commit 0c970fdccb
35 changed files with 1484 additions and 128 deletions

View File

@ -64,6 +64,12 @@ dependencies {
implementation 'com.sackcentury:shinebutton:1.0.0'
//
implementation 'com.blankj:utilcodex:1.28.4'
//
implementation 'com.wdullaer:materialdatetimepicker:4.2.3'
//
implementation('com.github.ihsanbal:LoggingInterceptor:3.1.0') {
exclude group: 'org.json', module: 'json'
}
//
//implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.5.6'
//

View File

@ -22,6 +22,7 @@
android:usesCleartextTraffic="true"
tools:ignore="UnusedAttribute"
tools:replace="android:allowBackup">
<activity android:name=".ui.home.NewPostActivity"></activity>
<activity
android:name=".ui.account.home.InputCodeActivity"
android:windowSoftInputMode="stateVisible" />

View File

@ -10,9 +10,12 @@ public class Const {
public static final String LOGIN_USER_NAME = "LoginUserName";
public static final String LOGIN_NICKNAME = "LoginNickname";
public static final String LOGIN_HEAD_URL = "LoginHeadUrl";
public static final String CUR_FAMILY_ID = "CurFamilyID";
public static final String CUR_FAMILY_NAME = "CUR.FAMILY.NAME";
public static final int CAMERA_OK = 1;
public static final int PIC_OK = 2;
public static final String BUCKET_NAME = "a-1300518338";
public static final String URL_Separator = "●●●●●●";
}

View File

@ -7,18 +7,18 @@ import android.widget.ImageView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.google.gson.GsonBuilder;
import com.ihsanbal.logging.Level;
import com.ihsanbal.logging.LoggingInterceptor;
import com.lzy.ninegrid.NineGridView;
import com.yuxihan.sdu.BuildConfig;
import com.yuxihan.sdu.R;
import com.yuxihan.sdu.comm.network.LoggingInterceptor;
import com.yuxihan.sdu.comm.util.UploadTencentSDK;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.internal.platform.Platform;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
@ -77,30 +77,28 @@ public class SDUApp extends Application {
}
private static void initRetrofit() {
LoggingInterceptor httpLoggingInterceptor = new LoggingInterceptor.Builder()
.loggable(BuildConfig.DEBUG)
.setLevel(Level.BASIC)
.log(Platform.INFO)
.request("Request")
.response("Response")
.build();
OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
//DEBUG模式下 添加日志拦截器
if (BuildConfig.DEBUG) {
httpClientBuilder.addInterceptor(new LoggingInterceptor());
}
//添加一个设置header拦截器
httpClientBuilder.addInterceptor(new Interceptor() {
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request mRequest = chain.request().newBuilder()
.header("User-Agent", "android/")
.build();
return chain.proceed(mRequest);
}
});
httpClientBuilder.addInterceptor(httpLoggingInterceptor);
httpClientBuilder.connectTimeout(60, TimeUnit.SECONDS);
mRetrofit = new Retrofit.Builder()
.client(httpClientBuilder.build())
.addConverterFactory(GsonConverterFactory.create(new GsonBuilder().setDateFormat(
"yyyy-MM-dd HH:mm").create()))
.baseUrl(Const.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
public static Context getAppContext(){
public static Context getAppContext() {
return SDUApp.appContext;
}
//61719636
//61878202
}

View File

@ -6,10 +6,12 @@ public class BaseRequestParams {
private String token;
private String userName;
private String familyId;
public BaseRequestParams() {
this.token = AccountUtils.getCurToken();
this.userName = AccountUtils.getCurUserName();
this.familyId = AccountUtils.getCurFamilyID();
}
public String getUserName() {
@ -27,4 +29,12 @@ public class BaseRequestParams {
public void setToken(String token) {
this.token = token;
}
public String getFamilyId() {
return familyId;
}
public void setFamilyId(String familyId) {
this.familyId = familyId;
}
}

View File

@ -1,33 +0,0 @@
package com.yuxihan.sdu.comm.network;
import android.util.Log;
import java.io.IOException;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.internal.annotations.EverythingIsNonNull;
@EverythingIsNonNull
public class LoggingInterceptor implements Interceptor {
private static final String TAG = "LoggingInterceptor";
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request();
long t1 = System.nanoTime();
Log.i(TAG, String.format("Sending request %s on %s%n%s",
request.url(), chain.connection(), request.headers()));
Response response = chain.proceed(request);
long t2 = System.nanoTime();
Log.i(TAG, String.format("Received response for %s in %.1fms%n%s",
response.request().url(), (t2 - t1) / 1e6d, response.headers()));
Log.i(TAG, response.toString());
return response;
}
}

View File

@ -12,12 +12,14 @@ public class AccountUtils {
* 保存登陆状态
*/
public static void saveLoginState(String userName, String token, String nickName,
String headUrl) {
String headUrl, String curFamilyID, String curFamilyName) {
SPUtils.getInstance().put(Const.LOGIN_STATE, true);
SPUtils.getInstance().put(Const.LOGIN_TOKEN, token);
SPUtils.getInstance().put(Const.LOGIN_USER_NAME, userName);
SPUtils.getInstance().put(Const.LOGIN_NICKNAME, nickName);
SPUtils.getInstance().put(Const.LOGIN_HEAD_URL, headUrl);
SPUtils.getInstance().put(Const.CUR_FAMILY_ID, curFamilyID);
SPUtils.getInstance().put(Const.CUR_FAMILY_NAME, curFamilyName);
}
/**
@ -28,6 +30,26 @@ public class AccountUtils {
SPUtils.getInstance().put(Const.LOGIN_TOKEN, "");
SPUtils.getInstance().put(Const.LOGIN_USER_NAME, "");
SPUtils.getInstance().put(Const.LOGIN_NICKNAME, "");
SPUtils.getInstance().put(Const.CUR_FAMILY_ID, "");
SPUtils.getInstance().put(Const.CUR_FAMILY_NAME, "");
}
public static void setCurFamilyID(String curFamilyID) {
SPUtils.getInstance().put(Const.CUR_FAMILY_ID, curFamilyID);
}
public static String getCurFamilyID() {
String ret = SPUtils.getInstance().getString(Const.CUR_FAMILY_ID);
return DataUtil.isEmpty(ret) ? "" : ret;
}
public static void setCurFamilyName(String curFamilyName) {
SPUtils.getInstance().put(Const.CUR_FAMILY_NAME, curFamilyName);
}
public static String getCurFamilyName() {
String ret = SPUtils.getInstance().getString(Const.CUR_FAMILY_NAME);
return DataUtil.isEmpty(ret) ? "" : ret;
}
public static String getCurUserName() {

View File

@ -0,0 +1,33 @@
package com.yuxihan.sdu.comm.util;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import java.io.File;
public class URIUtils {
public static Uri getImageContentUri(Context context, String path) {
Cursor cursor =
context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Images.Media._ID}, MediaStore.Images.Media.DATA + "=? ",
new String[]{path}, null);
if (cursor != null && cursor.moveToFirst()) {
int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID));
Uri baseUri = Uri.parse("content://media/external/images/media");
return Uri.withAppendedPath(baseUri, "" + id);
} else {
// 如果图片不在手机的共享图片数据库就先把它插入
if (new File(path).exists()) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATA, path);
return context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
} else {
return null;
}
}
}
}

View File

@ -0,0 +1,99 @@
package com.yuxihan.sdu.comm.widget;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
public class FullyGridLayoutManager extends GridLayoutManager {
public FullyGridLayoutManager(Context context, int spanCount) {
super(context, spanCount);
}
public FullyGridLayoutManager(Context context, int spanCount, int orientation,
boolean reverseLayout) {
super(context, spanCount, orientation, reverseLayout);
}
private int[] mMeasuredDimension = new int[2];
@Override
public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec
, int heightSpec) {
final int widthMode = View.MeasureSpec.getMode(widthSpec);
final int heightMode = View.MeasureSpec.getMode(heightSpec);
final int widthSize = View.MeasureSpec.getSize(widthSpec);
final int heightSize = View.MeasureSpec.getSize(heightSpec);
int width = 0;
int height = 0;
int count = getItemCount();
int span = getSpanCount();
for (int i = 0; i < count; i++) {
measureScrapChild(recycler, i,
View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
mMeasuredDimension);
if (getOrientation() == HORIZONTAL) {
if (i % span == 0) {
width = width + mMeasuredDimension[0];
}
if (i == 0) {
height = mMeasuredDimension[1];
}
} else {
if (i % span == 0) {
height = height + mMeasuredDimension[1];
}
if (i == 0) {
width = mMeasuredDimension[0];
}
}
}
switch (widthMode) {
case View.MeasureSpec.EXACTLY:
width = widthSize;
case View.MeasureSpec.AT_MOST:
case View.MeasureSpec.UNSPECIFIED:
}
switch (heightMode) {
case View.MeasureSpec.EXACTLY:
height = heightSize;
case View.MeasureSpec.AT_MOST:
case View.MeasureSpec.UNSPECIFIED:
}
setMeasuredDimension(width, height);
}
final RecyclerView.State mState = new RecyclerView.State();
private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,
int heightSpec, int[] measuredDimension) {
int itemCount = mState.getItemCount();
if (position < itemCount) {
try {
View view = recycler.getViewForPosition(0);
if (view != null) {
RecyclerView.LayoutParams p =
(RecyclerView.LayoutParams) view.getLayoutParams();
int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec,
getPaddingLeft() + getPaddingRight(), p.width);
int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec,
getPaddingTop() + getPaddingBottom(), p.height);
view.measure(childWidthSpec, childHeightSpec);
measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin;
measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin;
recycler.recycleView(view);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

View File

@ -8,8 +8,8 @@ import com.yuxihan.sdu.data.model.RegParams;
import com.yuxihan.sdu.data.model.SMSParams;
import com.yuxihan.sdu.data.model.UpdateNicknameParams;
import com.yuxihan.sdu.data.model.UpdateUserHeadParams;
import com.yuxihan.sdu.ui.account.AccountViewModel;
import com.yuxihan.sdu.ui.account.HomeBean;
import com.yuxihan.sdu.ui.home.PostRequestParams;
import retrofit2.Call;
import retrofit2.http.Body;
@ -31,24 +31,30 @@ public interface UpdateService {
Call<DataBean> hi(
);
@POST("/updateUserHead")
Call<DataBean> updateUserHead(
@Body UpdateUserHeadParams params
@Body UpdateUserHeadParams params
);
@POST("/updateName")
Call<DataBean> updateNickname(
@Body UpdateNicknameParams params
@Body UpdateNicknameParams params
);
@POST("/sendSms")
Call<DataBean> sendSMS(
@Body SMSParams params
@Body SMSParams params
);
@POST("/getFamilyList")
Call<Result<HomeBean>> getFamilyList(
@Body BaseRequestParams params
@Body BaseRequestParams params
);
@POST("/savePostDetail")
Call<Result> savePostDetail(
@Body PostRequestParams params
);
}

View File

@ -5,6 +5,25 @@ public class LoginRetVo {
private String token;
private String nickname;
private String userHead;
private String familyName;
private String familyId;
public String getFamilyName() {
return familyName;
}
public void setFamilyName(String familyName) {
this.familyName = familyName;
}
public String getFamilyId() {
return familyId;
}
public void setFamilyId(String familyId) {
this.familyId = familyId;
}
public String getToken() {
return token;

View File

@ -6,23 +6,11 @@ import android.widget.Toast;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import com.tencent.cos.xml.exception.CosXmlClientException;
import com.tencent.cos.xml.exception.CosXmlServiceException;
import com.tencent.cos.xml.listener.CosXmlProgressListener;
import com.tencent.cos.xml.listener.CosXmlResultListener;
import com.tencent.cos.xml.model.CosXmlRequest;
import com.tencent.cos.xml.model.CosXmlResult;
import com.tencent.cos.xml.transfer.COSXMLUploadTask;
import com.tencent.cos.xml.transfer.TransferState;
import com.tencent.cos.xml.transfer.TransferStateListener;
import com.yuxihan.sdu.comm.Const;
import com.yuxihan.sdu.comm.SDUApp;
import com.yuxihan.sdu.comm.util.UploadTencentSDK;
import com.yuxihan.sdu.data.UpdateService;
import com.yuxihan.sdu.data.model.DataBean;
import com.yuxihan.sdu.data.model.UpdateNicknameParams;
import com.yuxihan.sdu.data.model.UpdateUserHeadParams;
import com.yuxihan.sdu.ui.info.UpdateNicknameState;
import com.yuxihan.sdu.ui.info.UpdateUserHeadState;
import retrofit2.Call;
@ -44,7 +32,11 @@ public class PostDetailViewModel extends ViewModel {
@Override
public void onResponse(Call<DataBean> call, Response<DataBean> response) {
//请求成功返回是一个封装为DataBean的响应
Log.e("TAG", "接口返回内容 ===== " + response.body().getResult());
if (null == response.body()) {
Toast.makeText(SDUApp.getAppContext(), "Internal Server Error",
Toast.LENGTH_LONG).show();
return;
}
if (Const.ERROR_CODE_NORMAL.equals(response.body().getErrCode())) {
// updateNicknameState.setValue(new UpdateNicknameState(nickname));
} else {

View File

@ -8,6 +8,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.lifecycle.Observer;
@ -19,6 +20,7 @@ import com.yuxihan.sdu.comm.BaseFragment;
import com.yuxihan.sdu.comm.Const;
import com.yuxihan.sdu.comm.util.AccountUtils;
import com.yuxihan.sdu.comm.util.DataUtil;
import com.yuxihan.sdu.comm.widget.selector.SelectorGroup;
import com.yuxihan.sdu.ui.account.home.CreateHomeActivity;
import com.yuxihan.sdu.ui.account.home.InputCodeActivity;
import com.yuxihan.sdu.ui.baby.BabyListActivity;
@ -67,10 +69,21 @@ public class AccountFragment extends BaseFragment implements View.OnClickListene
accountViewModel.getHomeBean().observe(getViewLifecycleOwner(), new Observer<HomeBean>() {
@Override
public void onChanged(HomeBean homeBean) {
SelectorGroup selectorGroup = new SelectorGroup();
homeList.removeAllViews();
for (HomeBean.FamilyListBean bean : homeBean.getFamilyList()) {
homeList.addView(new AgeSelector(getContext()));
for (HomeBean.FamilyBean bean : homeBean.getFamilyList()) {
AgeSelector ageSelector = new AgeSelector(getContext());
ageSelector.setFamilyInfo(bean);
ageSelector.setGroup("", selectorGroup);
ageSelector.setTag(bean.getFamilyId());
homeList.addView(ageSelector);
}
selectorGroup.setStateListener(new SelectorGroup.StateListener() {
@Override
public void onStateChange(String groupTag, String tag, boolean isSelected) {
Toast.makeText(getContext(), tag + "被选中", Toast.LENGTH_LONG).show();
}
});
}
});

View File

@ -44,7 +44,11 @@ public class AccountViewModel extends ViewModel {
public void onResponse(Call<Result<HomeBean>> call,
Response<Result<HomeBean>> response) {
//请求成功返回是一个封装为DataBean的响应
Log.e("TAG", "接口返回内容 ===== " + response.body().getResult());
if (null == response.body()) {
Toast.makeText(SDUApp.getAppContext(), "Internal Server Error",
Toast.LENGTH_LONG).show();
return;
}
if (Const.ERROR_CODE_NORMAL.equals(response.body().getErrCode())) {
homeBean.setValue(response.body().getResult());
} else {

View File

@ -5,7 +5,6 @@ import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
@ -13,16 +12,19 @@ import android.widget.ImageView;
import android.widget.TextView;
import com.yuxihan.sdu.R;
import com.yuxihan.sdu.comm.util.AccountUtils;
import com.yuxihan.sdu.comm.widget.selector.Selector;
public class AgeSelector extends Selector {
private TextView tvTitle;
private TextView tv_record_member_count;
private TextView tv_creator;
private ImageView ivIcon;
private ImageView ivSelector;
private ValueAnimator valueAnimator;
private String text;
private int iconResId;
private int indicatorResId;
private int indicatorResId = R.drawable.ic_selected;
private int textColor;
private int textSize;
@ -38,14 +40,15 @@ public class AgeSelector extends Selector {
super(context, attrs, defStyleAttr);
}
private void onBindView(String text, int iconResId, int indicatorResId, int textColor, int textSize) {
private void onBindView(String text, int iconResId, int indicatorResId, int textColor,
int textSize) {
if (tvTitle != null) {
tvTitle.setText(text);
tvTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize);
tvTitle.setTextColor(textColor);
// tvTitle.setText(text);
// tvTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize);
// tvTitle.setTextColor(textColor);
}
if (ivIcon != null) {
ivIcon.setImageResource(iconResId);
// ivIcon.setImageResource(iconResId);
}
if (ivSelector != null) {
ivSelector.setImageResource(indicatorResId);
@ -58,7 +61,8 @@ public class AgeSelector extends Selector {
text = typedArray.getString(R.styleable.Selector_text);
iconResId = typedArray.getResourceId(R.styleable.Selector_img, 0);
indicatorResId = typedArray.getResourceId(R.styleable.Selector_indicator, 0);
textColor = typedArray.getColor(R.styleable.Selector_text_color, Color.parseColor("#FF222222"));
textColor = typedArray.getColor(R.styleable.Selector_text_color, Color.parseColor(
"#FF222222"));
textSize = typedArray.getInteger(R.styleable.Selector_text_size, 15);
}
@ -67,11 +71,29 @@ public class AgeSelector extends Selector {
View view = LayoutInflater.from(this.getContext()).inflate(R.layout.item_home, null);
tvTitle = view.findViewById(R.id.tv_home_name);
ivIcon = view.findViewById(R.id.iv_home_head);
tv_record_member_count = view.findViewById(R.id.tv_record_member_count);
tv_creator = view.findViewById(R.id.tv_creator);
ivSelector = view.findViewById(R.id.iv_select_status);
onBindView(text, iconResId, indicatorResId, textColor, textSize);
return view;
}
public void setFamilyInfo(HomeBean.FamilyBean familyBean) {
tvTitle.setText(familyBean.getFamilyName());
tv_record_member_count.setText(getResources().getString(R.string.count_show,
familyBean.getRecordCount(), familyBean.getMembersCount()));
if (AccountUtils.getCurUserName().equals(familyBean.getUserId())) {
tv_creator.setVisibility(VISIBLE);
} else {
tv_creator.setVisibility(GONE);
}
if (AccountUtils.getCurFamilyID().equals(familyBean.getFamilyId() + "")) {
setSelected(true);
} else {
setSelected(false);
}
}
@Override
protected void onSwitchSelected(boolean isSelect) {
if (isSelect) {

View File

@ -4,17 +4,17 @@ import java.util.List;
public class HomeBean {
private List<FamilyListBean> familyList;
private List<FamilyBean> familyList;
public List<FamilyListBean> getFamilyList() {
public List<FamilyBean> getFamilyList() {
return familyList;
}
public void setFamilyList(List<FamilyListBean> familyList) {
public void setFamilyList(List<FamilyBean> familyList) {
this.familyList = familyList;
}
public static class FamilyListBean {
public static class FamilyBean {
/**
* familyName : 狗胖
* familyId : 3

View File

@ -1,13 +1,13 @@
package com.yuxihan.sdu.ui.baby;
import android.util.Log;
import android.widget.Toast;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import com.yuxihan.sdu.comm.Const;
import com.yuxihan.sdu.comm.SDUApp;
import com.yuxihan.sdu.comm.util.AccountUtils;
import com.yuxihan.sdu.data.UpdateService;
import com.yuxihan.sdu.data.model.DataBean;
import com.yuxihan.sdu.data.model.LoggedInUser;
@ -20,7 +20,7 @@ import retrofit2.Response;
public class BabyListViewModel extends ViewModel {
private MutableLiveData<LoggedInUser> loggedInUser = new MutableLiveData<>();
public void login(final String username, String password) {
public void login1(final String username, String password) {
UpdateService updateService = SDUApp.getRetrofit().create(UpdateService.class);
Call<DataBean> call = updateService.login(new LoginParams(username, password));
@ -28,13 +28,13 @@ public class BabyListViewModel extends ViewModel {
@Override
public void onResponse(Call<DataBean> call, Response<DataBean> response) {
//请求成功返回是一个封装为DataBean的响应
Log.e("TAG", "接口返回内容 ===== " + response.body().getResult());
if (null == response.body()) {
Toast.makeText(SDUApp.getAppContext(), "Internal Server Error",
Toast.LENGTH_LONG).show();
return;
}
if (Const.ERROR_CODE_NORMAL.equals(response.body().getErrCode())) {
String token = response.body().getResult().getToken();
String nickName = response.body().getResult().getNickname();
String userHead = response.body().getResult().getUserHead();
loggedInUser.setValue(new LoggedInUser(username, username));
AccountUtils.saveLoginState(username, token, nickName, userHead);
} else {
loggedInUser.setValue(new LoggedInUser(username, response.body().getErrMsg(),
false));

View File

@ -1,5 +1,6 @@
package com.yuxihan.sdu.ui.home;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
@ -21,14 +22,16 @@ import com.yuxihan.sdu.ui.home.adapter.HomeListAdapter;
import java.util.ArrayList;
public class HomeFragment extends BaseFragment {
public class HomeFragment extends BaseFragment implements View.OnClickListener {
private HomeModel homeModel;
private HomeViewModel homeViewModel;
private View add_new_post;
private View add_new_post_pic;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
homeModel =
new ViewModelProvider(this).get(HomeModel.class);
homeViewModel =
new ViewModelProvider(this).get(HomeViewModel.class);
View root = inflater.inflate(R.layout.fragment_home, container, false);
initView(root);
return root;
@ -36,6 +39,12 @@ public class HomeFragment extends BaseFragment {
private void initView(View root) {
add_new_post = root.findViewById(R.id.add_new_post);
add_new_post.setOnClickListener(this);
add_new_post_pic = root.findViewById(R.id.add_new_post_pic);
add_new_post_pic.setOnClickListener(this);
TwinklingRefreshLayout refreshLayout = root.findViewById(R.id.refreshLayout);
refreshLayout.setOnRefreshListener(new RefreshListenerAdapter() {
@Override
@ -64,12 +73,27 @@ public class HomeFragment extends BaseFragment {
growListRV.setHasFixedSize(true);
HomeListAdapter homeListAdapter = new HomeListAdapter(null);
growListRV.setAdapter(homeListAdapter);
homeModel.getPostListLD().observe(getViewLifecycleOwner(), new Observer<ArrayList<PostDetailBean>>() {
@Override
public void onChanged(ArrayList<PostDetailBean> postDetailBeans) {
homeListAdapter.updateData(postDetailBeans);
}
homeViewModel.getPostListLD().observe(getViewLifecycleOwner(),
new Observer<ArrayList<PostDetailBean>>() {
@Override
public void onChanged(ArrayList<PostDetailBean> postDetailBeans) {
homeListAdapter.updateData(postDetailBeans);
}
});
});
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.add_new_post:
startActivity(new Intent(getContext(), NewPostActivity.class));
break;
case R.id.add_new_post_pic:
startActivity(new Intent(getContext(), NewPostActivity.class));
break;
default:
break;
}
}
}

View File

@ -7,23 +7,32 @@ import com.yuxihan.sdu.data.model.PostDetailBean;
import java.util.ArrayList;
public class HomeModel extends ViewModel {
public class HomeViewModel extends ViewModel {
private MutableLiveData<String> mText;
private MutableLiveData<ArrayList<PostDetailBean>> postListLD;
public HomeModel() {
public HomeViewModel() {
postListLD = new MutableLiveData<>();
ArrayList<String> picUrlList = new ArrayList<>();
picUrlList.add("http://t9.baidu.com/it/u=188672807,2175104643&fm=79&app=86&f=JPEG?w=1280&h=853");
picUrlList.add("http://t9.baidu.com/it/u=3989902316,3793481456&fm=79&app=86&f=JPEG?w=1280&h=853");
picUrlList.add("http://t9.baidu.com/it/u=1038289730,4068396403&fm=79&app=86&f=JPEG?w=1280&h=853");
picUrlList.add("http://t8.baidu.com/it/u=3346148719,3315269675&fm=79&app=86&f=JPEG?w=666&h=1000");
picUrlList.add("http://t7.baidu.com/it/u=1263664584,1982855955&fm=79&app=86&f=JPEG?w=534&h=800");
picUrlList.add("http://t7.baidu.com/it/u=2832630561,1836266954&fm=79&app=86&f=JPEG?w=667&h=1000");
picUrlList.add("http://t8.baidu.com/it/u=3647266255,2679682355&fm=79&app=86&f=JPEG?w=667&h=1000");
picUrlList.add("http://t7.baidu.com/it/u=558764796,419343714&fm=79&app=86&f=JPEG?w=667&h=1000");
picUrlList.add("http://t7.baidu.com/it/u=4047929277,3427505730&fm=79&app=86&f=JPEG?w=667&h=1000");
picUrlList.add("http://t9.baidu.com/it/u=188672807," +
"2175104643&fm=79&app=86&f=JPEG?w=1280&h=853");
picUrlList.add("http://t9.baidu.com/it/u=3989902316," +
"3793481456&fm=79&app=86&f=JPEG?w=1280&h=853");
picUrlList.add("http://t9.baidu.com/it/u=1038289730," +
"4068396403&fm=79&app=86&f=JPEG?w=1280&h=853");
picUrlList.add("http://t8.baidu.com/it/u=3346148719," +
"3315269675&fm=79&app=86&f=JPEG?w=666&h=1000");
picUrlList.add("http://t7.baidu.com/it/u=1263664584," +
"1982855955&fm=79&app=86&f=JPEG?w=534&h=800");
picUrlList.add("http://t7.baidu.com/it/u=2832630561," +
"1836266954&fm=79&app=86&f=JPEG?w=667&h=1000");
picUrlList.add("http://t8.baidu.com/it/u=3647266255," +
"2679682355&fm=79&app=86&f=JPEG?w=667&h=1000");
picUrlList.add("http://t7.baidu.com/it/u=558764796," +
"419343714&fm=79&app=86&f=JPEG?w=667&h=1000");
picUrlList.add("http://t7.baidu.com/it/u=4047929277," +
"3427505730&fm=79&app=86&f=JPEG?w=667&h=1000");
ArrayList<PostDetailBean> postList = new ArrayList<>();
for (int i = 0; i < 100; i++) {
postList.add(new PostDetailBean("0000" + i, "雨曦大魔王" + i, "http://jzvd-pic.nathen" +

View File

@ -0,0 +1,453 @@
package com.yuxihan.sdu.ui.home;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Canvas;
import android.os.Bundle;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;
import com.blankj.utilcode.util.TimeUtils;
import com.luck.picture.lib.PictureSelector;
import com.luck.picture.lib.broadcast.BroadcastAction;
import com.luck.picture.lib.broadcast.BroadcastManager;
import com.luck.picture.lib.config.PictureConfig;
import com.luck.picture.lib.config.PictureMimeType;
import com.luck.picture.lib.decoration.GridSpacingItemDecoration;
import com.luck.picture.lib.entity.LocalMedia;
import com.luck.picture.lib.listener.OnResultCallbackListener;
import com.luck.picture.lib.tools.ScreenUtils;
import com.luck.picture.lib.tools.ToastUtils;
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;
import com.yuxihan.sdu.R;
import com.yuxihan.sdu.comm.BaseActivity;
import com.yuxihan.sdu.comm.Const;
import com.yuxihan.sdu.comm.util.AccountUtils;
import com.yuxihan.sdu.comm.util.GlideEngine;
import com.yuxihan.sdu.comm.widget.FullyGridLayoutManager;
import com.yuxihan.sdu.ui.home.adapter.DragListener;
import com.yuxihan.sdu.ui.home.adapter.GridImageAdapter;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
public class NewPostActivity extends BaseActivity implements View.OnClickListener,
DatePickerDialog.OnDateSetListener {
private GridImageAdapter mAdapter;
private boolean isUpward;
private boolean needScaleBig = true;
private boolean needScaleSmall = true;
private int maxSelectNum = 9;
private ItemTouchHelper mItemTouchHelper;
private DragListener mDragListener;
private View rl_record_time;
private TextView tv_record_time;
private TextView tv_post_to;
private String selectedDate;
private NewPostViewModel newPostViewModel;
private EditText et_post_text_content;
private PostRequestParams postRequestParams = new PostRequestParams();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_post);
newPostViewModel = new ViewModelProvider(this).get(NewPostViewModel.class);
initView();
initPicSelect(savedInstanceState);
}
private void initView() {
tv_record_time = findViewById(R.id.tv_record_time);
findViewById(R.id.iv_back).setOnClickListener(this);
tv_post_to = findViewById(R.id.tv_post_to);
tv_post_to.setText(AccountUtils.getCurFamilyName());
selectedDate = TimeUtils.millis2String(new Date().getTime(), "yyyy-MM-dd");
tv_record_time.setText(selectedDate);
postRequestParams.setPostTime(selectedDate);
findViewById(R.id.btn_submit).setOnClickListener(this);
et_post_text_content = findViewById(R.id.et_post_text_content);
rl_record_time = findViewById(R.id.rl_record_time);
rl_record_time.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.iv_back:
finish();
break;
case R.id.rl_record_time:
Calendar now = Calendar.getInstance();
DatePickerDialog dpd = DatePickerDialog.newInstance(
NewPostActivity.this,
now.get(Calendar.YEAR),
now.get(Calendar.MONTH),
now.get(Calendar.DAY_OF_MONTH)
);
dpd.show(getSupportFragmentManager(), "Datepickerdialog");
break;
case R.id.btn_submit:
if (check()) {
newPostViewModel.post(postRequestParams);
finish();
}
break;
default:
break;
}
}
private boolean check() {
String postTextContent = et_post_text_content.getText().toString().trim();
List<LocalMedia> mAdapterData = mAdapter.getData();
if (TextUtils.isEmpty(postTextContent)
&& mAdapterData.size() == 0) {
Toast.makeText(NewPostActivity.this, "请输入点啥再提交吧~", Toast.LENGTH_LONG).show();
return false;
}
if (!TextUtils.isEmpty(postTextContent)) {
postRequestParams.setPostTextContent(postTextContent);
}
if (mAdapterData.size() > 0) {
postRequestParams.setPostPicUrls(listToString(mAdapterData));
}
return true;
}
private String listToString(List<LocalMedia> mAdapterData) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < mAdapterData.size(); i++) {
sb.append(mAdapterData.get(i).getPath());
if (i != mAdapterData.size() - 1) {
sb.append(Const.URL_Separator);
}
}
return sb.toString();
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (TextUtils.isEmpty(action)) {
return;
}
if (BroadcastAction.ACTION_DELETE_PREVIEW_POSITION.equals(action)) {
// 外部预览删除按钮回调
Bundle extras = intent.getExtras();
if (extras != null) {
int position = extras.getInt(PictureConfig.EXTRA_PREVIEW_DELETE_POSITION);
ToastUtils.s(NewPostActivity.this, "delete image index:" + position);
mAdapter.remove(position);
mAdapter.notifyItemRemoved(position);
}
}
}
};
/**
* 重置
*/
private void resetState() {
if (mDragListener != null) {
mDragListener.deleteState(false);
mDragListener.dragState(false);
}
isUpward = false;
}
private GridImageAdapter.onAddPicClickListener onAddPicClickListener =
new GridImageAdapter.onAddPicClickListener() {
@Override
public void onAddPicClick() {
PictureSelector.create(NewPostActivity.this)
.openGallery(PictureMimeType.ofImage())// 全部.PictureMimeType.ofAll()
.theme(R.style.picture_white_style)// 主题样式设置 具体参考 values/styles
.maxSelectNum(9)// 最大图片选择数量
.loadImageEngine(GlideEngine.createGlideEngine())
.minSelectNum(1)// 最小选择数量
.isCamera(true)// 是否显示拍照按钮
.imageSpanCount(4)// 每行显示个数
.isCompress(false)// 是否压缩 true or false
.isMaxSelectEnabledMask(true)
.compressQuality(60)
.isZoomAnim(true)// 图片列表点击 缩放效果 默认true
.synOrAsy(true)//同步true或异步false 压缩 默认同步
.glideOverride(120, 120)// glide 加载宽高越小图片列表越流畅但会影响列表图片浏览的清晰度
.withAspectRatio(1, 1)
.selectionData(mAdapter.getData())
.forResult(new MyResultCallback(mAdapter));//结果回调
}
};
@Override
public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) {
String date = year + "-" + (monthOfYear + 1) + "-" + dayOfMonth;
long l = TimeUtils.string2Millis(date, "yyyy-MM-dd");
selectedDate = TimeUtils.millis2String(l, "yyyy-MM-dd");
tv_record_time.setText(selectedDate);
}
/**
* 返回结果回调
*/
private static class MyResultCallback implements OnResultCallbackListener<LocalMedia> {
private static final String TAG = "MyResultCallback";
private WeakReference<GridImageAdapter> mAdapterWeakReference;
public MyResultCallback(GridImageAdapter adapter) {
super();
this.mAdapterWeakReference = new WeakReference<>(adapter);
}
@Override
public void onResult(List<LocalMedia> result) {
for (LocalMedia media : result) {
Log.i(TAG, "是否压缩:" + media.isCompressed());
Log.i(TAG, "压缩:" + media.getCompressPath());
Log.i(TAG, "原图:" + media.getPath());
Log.i(TAG, "是否裁剪:" + media.isCut());
Log.i(TAG, "裁剪:" + media.getCutPath());
Log.i(TAG, "是否开启原图:" + media.isOriginal());
Log.i(TAG, "原图路径:" + media.getOriginalPath());
Log.i(TAG, "Android Q 特有Path:" + media.getAndroidQToPath());
Log.i(TAG, "宽高: " + media.getWidth() + "x" + media.getHeight());
Log.i(TAG, "Size: " + media.getSize());
}
if (mAdapterWeakReference.get() != null) {
mAdapterWeakReference.get().setList(result);
mAdapterWeakReference.get().notifyDataSetChanged();
}
}
@Override
public void onCancel() {
Log.i(TAG, "PictureSelector Cancel");
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (mAdapter != null && mAdapter.getData() != null && mAdapter.getData().size() > 0) {
outState.putParcelableArrayList("selectorList",
(ArrayList<? extends Parcelable>) mAdapter.getData());
}
}
/**
* 初始化图片选择
*/
private void initPicSelect(Bundle savedInstanceState) {
RecyclerView mRecyclerView = findViewById(R.id.recycler);
FullyGridLayoutManager manager = new FullyGridLayoutManager(this,
3, GridLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(manager);
mRecyclerView.addItemDecoration(new GridSpacingItemDecoration(4,
ScreenUtils.dip2px(this, 8), false));
mAdapter = new GridImageAdapter(NewPostActivity.this, onAddPicClickListener);
if (savedInstanceState != null && savedInstanceState.getParcelableArrayList("selectorList"
) != null) {
mAdapter.setList(savedInstanceState.getParcelableArrayList("selectorList"));
}
mAdapter.setSelectMax(9);
mRecyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener((v, position) -> {
List<LocalMedia> selectList = mAdapter.getData();
if (selectList.size() > 0) {
LocalMedia media = selectList.get(position);
String mimeType = media.getMimeType();
int mediaType = PictureMimeType.getMimeType(mimeType);
switch (mediaType) {
case PictureConfig.TYPE_VIDEO:
// 预览视频
PictureSelector.create(NewPostActivity.this)
.themeStyle(R.style.picture_white_style)
//.setPictureStyle(mPictureParameterStyle)// 动态自定义相册主题
.externalPictureVideo(TextUtils.isEmpty(media.getAndroidQToPath()) ? media.getPath() : media.getAndroidQToPath());
break;
case PictureConfig.TYPE_AUDIO:
// 预览音频
PictureSelector.create(NewPostActivity.this)
.externalPictureAudio(PictureMimeType.isContent(media.getPath())
? media.getAndroidQToPath() : media.getPath());
break;
default:
PictureSelector.create(NewPostActivity.this)
.themeStyle(R.style.picture_white_style) // xml设置主题
//.setPictureStyle(mPictureParameterStyle)// 动态自定义相册主题
//.setPictureWindowAnimationStyle(animationStyle)// 自定义页面启动动画
.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)// 设置相册Activity方向不设置默认使用系统
.isNotPreviewDownload(true)// 预览图片长按是否可以下载
//.bindCustomPlayVideoCallback(new MyVideoSelectedPlayCallback
// (getContext()))// 自定义播放回调控制用户可以使用自己的视频播放界面
.imageEngine(GlideEngine.createGlideEngine())// 外部传入图片加载引擎必传项
.openExternalPreview(position, selectList);
break;
}
}
});
mAdapter.setItemLongClickListener((holder, position, v) -> {
//如果item不是最后一个则执行拖拽
needScaleBig = true;
needScaleSmall = true;
int size = mAdapter.getData().size();
if (size != maxSelectNum) {
mItemTouchHelper.startDrag(holder);
return;
}
if (holder.getLayoutPosition() != size - 1) {
mItemTouchHelper.startDrag(holder);
}
});
mItemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() {
@Override
public boolean isLongPressDragEnabled() {
return true;
}
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
}
@Override
public int getMovementFlags(@NonNull RecyclerView recyclerView,
@NonNull RecyclerView.ViewHolder viewHolder) {
int itemViewType = viewHolder.getItemViewType();
if (itemViewType != GridImageAdapter.TYPE_CAMERA) {
viewHolder.itemView.setAlpha(0.7f);
}
return makeMovementFlags(ItemTouchHelper.DOWN | ItemTouchHelper.UP
| ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT, 0);
}
@Override
public boolean onMove(@NonNull RecyclerView recyclerView,
@NonNull RecyclerView.ViewHolder viewHolder,
@NonNull RecyclerView.ViewHolder target) {
//得到item原来的position
try {
int fromPosition = viewHolder.getAdapterPosition();
//得到目标position
int toPosition = target.getAdapterPosition();
int itemViewType = target.getItemViewType();
if (itemViewType != GridImageAdapter.TYPE_CAMERA) {
if (fromPosition < toPosition) {
for (int i = fromPosition; i < toPosition; i++) {
Collections.swap(mAdapter.getData(), i, i + 1);
}
} else {
for (int i = fromPosition; i > toPosition; i--) {
Collections.swap(mAdapter.getData(), i, i - 1);
}
}
mAdapter.notifyItemMoved(fromPosition, toPosition);
}
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
@Override
public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView,
@NonNull RecyclerView.ViewHolder viewHolder, float dX,
float dY, int actionState, boolean isCurrentlyActive) {
int itemViewType = viewHolder.getItemViewType();
if (itemViewType != GridImageAdapter.TYPE_CAMERA) {
if (null == mDragListener) {
return;
}
if (needScaleBig) {
//如果需要执行放大动画
viewHolder.itemView.animate().scaleXBy(0.1f).scaleYBy(0.1f).setDuration(100);
//执行完成放大动画,标记改掉
needScaleBig = false;
//默认不需要执行缩小动画当执行完成放大 并且松手后才允许执行
needScaleSmall = false;
}
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState,
isCurrentlyActive);
}
}
@Override
public void onSelectedChanged(@Nullable RecyclerView.ViewHolder viewHolder,
int actionState) {
int itemViewType = viewHolder != null ? viewHolder.getItemViewType() :
GridImageAdapter.TYPE_CAMERA;
if (itemViewType != GridImageAdapter.TYPE_CAMERA) {
if (ItemTouchHelper.ACTION_STATE_DRAG == actionState && mDragListener != null) {
mDragListener.dragState(true);
}
super.onSelectedChanged(viewHolder, actionState);
}
}
@Override
public long getAnimationDuration(@NonNull RecyclerView recyclerView,
int animationType, float animateDx, float animateDy) {
needScaleSmall = true;
isUpward = true;
return super.getAnimationDuration(recyclerView, animationType, animateDx,
animateDy);
}
@Override
public void clearView(@NonNull RecyclerView recyclerView,
@NonNull RecyclerView.ViewHolder viewHolder) {
int itemViewType = viewHolder.getItemViewType();
if (itemViewType != GridImageAdapter.TYPE_CAMERA) {
viewHolder.itemView.setAlpha(1.0f);
super.clearView(recyclerView, viewHolder);
mAdapter.notifyDataSetChanged();
resetState();
}
}
});
mDragListener = new DragListener() {
@Override
public void deleteState(boolean isDelete) {
}
@Override
public void dragState(boolean isStart) {
}
};
// 绑定拖拽事件
mItemTouchHelper.attachToRecyclerView(mRecyclerView);
// 注册广播
BroadcastManager.getInstance(NewPostActivity.this).registerReceiver(broadcastReceiver,
BroadcastAction.ACTION_DELETE_PREVIEW_POSITION);
}
}

View File

@ -0,0 +1,51 @@
package com.yuxihan.sdu.ui.home;
import android.util.Log;
import android.widget.Toast;
import androidx.lifecycle.ViewModel;
import com.yuxihan.sdu.comm.Const;
import com.yuxihan.sdu.comm.SDUApp;
import com.yuxihan.sdu.data.Result;
import com.yuxihan.sdu.data.UpdateService;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class NewPostViewModel extends ViewModel {
public void post(PostRequestParams postRequestParams) {
UpdateService updateService = SDUApp.getRetrofit().create(UpdateService.class);
Call<Result> call = updateService.savePostDetail(postRequestParams);
call.enqueue(new Callback<Result>() {
@Override
public void onResponse(Call<Result> call, Response<Result> response) {
//请求成功返回是一个封装为DataBean的响应
if (null == response.body()) {
Toast.makeText(SDUApp.getAppContext(), "Internal Server Error",
Toast.LENGTH_LONG).show();
return;
}
if (Const.ERROR_CODE_NORMAL.equals(response.body().getErrCode())) {
Toast.makeText(SDUApp.getAppContext(), "发送成功",
Toast.LENGTH_LONG).show();
} else {
Toast.makeText(SDUApp.getAppContext(), response.body().getErrMsg(),
Toast.LENGTH_LONG).show();
}
}
@Override
public void onFailure(Call<Result> call, Throwable t) {
//请求失败
Log.e("TAG", "请求失败:" + t.getMessage());
Toast.makeText(SDUApp.getAppContext(), "服务器开小差了!",
Toast.LENGTH_LONG).show();
}
});
}
}

View File

@ -0,0 +1,63 @@
package com.yuxihan.sdu.ui.home;
import com.yuxihan.sdu.comm.network.BaseRequestParams;
public class PostRequestParams extends BaseRequestParams {
/**
* userName : 15919474525
* familyId : 1
* babyId : 1
* postTextContent : 啦啦啦
* postVideoUrl : 13123131313
* postPicUrls : 43242342423432
* token : 559e4541-5e5a-442b-b346-25dea15af69c
*/
private String babyId;
private String postTextContent;
private String postVideoUrl;
private String postPicUrls;
private String postTime;
public String getPostTime() {
return postTime;
}
public void setPostTime(String postTime) {
this.postTime = postTime;
}
public String getBabyId() {
return babyId;
}
public void setBabyId(String babyId) {
this.babyId = babyId;
}
public String getPostTextContent() {
return postTextContent;
}
public void setPostTextContent(String postTextContent) {
this.postTextContent = postTextContent;
}
public String getPostVideoUrl() {
return postVideoUrl;
}
public void setPostVideoUrl(String postVideoUrl) {
this.postVideoUrl = postVideoUrl;
}
public String getPostPicUrls() {
return postPicUrls;
}
public void setPostPicUrls(String postPicUrls) {
this.postPicUrls = postPicUrls;
}
}

View File

@ -0,0 +1,22 @@
package com.yuxihan.sdu.ui.home.adapter;
/**
* @authorluck
* @date2020-01-13 17:00
* @describe拖拽监听事件
*/
public interface DragListener {
/**
* 是否将 item拖动到删除处根据状态改变颜色
*
* @param isDelete
*/
void deleteState(boolean isDelete);
/**
* 是否于拖拽状态
*
* @param start
*/
void dragState(boolean isStart);
}

View File

@ -0,0 +1,242 @@
package com.yuxihan.sdu.ui.home.adapter;
import android.content.Context;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.luck.picture.lib.config.PictureMimeType;
import com.luck.picture.lib.entity.LocalMedia;
import com.luck.picture.lib.listener.OnItemClickListener;
import com.luck.picture.lib.tools.DateUtils;
import com.yuxihan.sdu.R;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class GridImageAdapter extends
RecyclerView.Adapter<GridImageAdapter.ViewHolder> {
public static final String TAG = "PictureSelector";
public static final int TYPE_CAMERA = 1;
public static final int TYPE_PICTURE = 2;
private LayoutInflater mInflater;
private List<LocalMedia> list = new ArrayList<>();
private int selectMax = 9;
/**
* 点击添加图片跳转
*/
private onAddPicClickListener mOnAddPicClickListener;
public interface onAddPicClickListener {
void onAddPicClick();
}
/**
* 删除
*/
public void delete(int position) {
try {
if (position != RecyclerView.NO_POSITION && list.size() > position) {
list.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, list.size());
}
} catch (Exception e) {
e.printStackTrace();
}
}
public GridImageAdapter(Context context, onAddPicClickListener mOnAddPicClickListener) {
this.mInflater = LayoutInflater.from(context);
this.mOnAddPicClickListener = mOnAddPicClickListener;
}
public void setSelectMax(int selectMax) {
this.selectMax = selectMax;
}
public void setList(List<LocalMedia> list) {
this.list = list;
}
public List<LocalMedia> getData() {
return list == null ? new ArrayList<>() : list;
}
public void remove(int position) {
if (list != null && position < list.size()) {
list.remove(position);
}
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView mImg;
ImageView mIvDel;
TextView tvDuration;
public ViewHolder(View view) {
super(view);
mImg = view.findViewById(R.id.fiv);
mIvDel = view.findViewById(R.id.iv_del);
tvDuration = view.findViewById(R.id.tv_duration);
}
}
@Override
public int getItemCount() {
if (list.size() < selectMax) {
return list.size() + 1;
} else {
return list.size();
}
}
@Override
public int getItemViewType(int position) {
if (isShowAddItem(position)) {
return TYPE_CAMERA;
} else {
return TYPE_PICTURE;
}
}
/**
* 创建ViewHolder
*/
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = mInflater.inflate(R.layout.gv_filter_image,
viewGroup, false);
final ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
private boolean isShowAddItem(int position) {
int size = list.size() == 0 ? 0 : list.size();
return position == size;
}
/**
* 设置值
*/
@Override
public void onBindViewHolder(final ViewHolder viewHolder, final int position) {
//少于8张显示继续添加的图标
if (getItemViewType(position) == TYPE_CAMERA) {
viewHolder.mImg.setImageResource(R.drawable.ic_add_image);
viewHolder.mImg.setOnClickListener(v -> mOnAddPicClickListener.onAddPicClick());
viewHolder.mIvDel.setVisibility(View.INVISIBLE);
} else {
viewHolder.mIvDel.setVisibility(View.VISIBLE);
viewHolder.mIvDel.setOnClickListener(view -> {
int index = viewHolder.getAdapterPosition();
// 这里有时会返回-1造成数据下标越界,具体可参考getAdapterPosition()源码
// 通过源码分析应该是bindViewHolder()暂未绘制完成导致知道原因的也可联系我~感谢
if (index != RecyclerView.NO_POSITION && list.size() > index) {
list.remove(index);
notifyItemRemoved(index);
notifyItemRangeChanged(index, list.size());
}
});
LocalMedia media = list.get(position);
if (media == null
|| TextUtils.isEmpty(media.getPath())) {
return;
}
int chooseModel = media.getChooseModel();
String path;
if (media.isCut() && !media.isCompressed()) {
// 裁剪过
path = media.getCutPath();
} else if (media.isCompressed() || (media.isCut() && media.isCompressed())) {
// 压缩过,或者裁剪同时压缩过,以最终压缩过图片为准
path = media.getCompressPath();
} else {
// 原图
path = media.getPath();
}
Log.i(TAG, "原图地址::" + media.getPath());
if (media.isCut()) {
Log.i(TAG, "裁剪地址::" + media.getCutPath());
}
if (media.isCompressed()) {
Log.i(TAG, "压缩地址::" + media.getCompressPath());
Log.i(TAG, "压缩后文件大小::" + new File(media.getCompressPath()).length() / 1024 + "k");
}
if (!TextUtils.isEmpty(media.getAndroidQToPath())) {
Log.i(TAG, "Android Q特有地址::" + media.getAndroidQToPath());
}
if (media.isOriginal()) {
Log.i(TAG, "是否开启原图功能::" + true);
Log.i(TAG, "开启原图功能后地址::" + media.getOriginalPath());
}
long duration = media.getDuration();
viewHolder.tvDuration.setVisibility(PictureMimeType.isHasVideo(media.getMimeType())
? View.VISIBLE : View.GONE);
if (chooseModel == PictureMimeType.ofAudio()) {
viewHolder.tvDuration.setVisibility(View.VISIBLE);
viewHolder.tvDuration.setCompoundDrawablesRelativeWithIntrinsicBounds
(R.drawable.picture_icon_audio, 0, 0, 0);
} else {
viewHolder.tvDuration.setCompoundDrawablesRelativeWithIntrinsicBounds
(R.drawable.picture_icon_video, 0, 0, 0);
}
viewHolder.tvDuration.setText(DateUtils.formatDurationTime(duration));
if (chooseModel == PictureMimeType.ofAudio()) {
viewHolder.mImg.setImageResource(R.drawable.picture_audio_placeholder);
} else {
Glide.with(viewHolder.itemView.getContext())
.load(PictureMimeType.isContent(path) && !media.isCut() && !media.isCompressed() ? Uri.parse(path)
: path)
.centerCrop()
.placeholder(R.color.app_color_f6)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(viewHolder.mImg);
}
//itemView 的点击事件
if (mItemClickListener != null) {
viewHolder.itemView.setOnClickListener(v -> {
int adapterPosition = viewHolder.getAdapterPosition();
mItemClickListener.onItemClick(v, adapterPosition);
});
}
if (mItemLongClickListener != null) {
viewHolder.itemView.setOnLongClickListener(v -> {
int adapterPosition = viewHolder.getAdapterPosition();
mItemLongClickListener.onItemLongClick(viewHolder, adapterPosition, v);
return true;
});
}
}
}
private OnItemClickListener mItemClickListener;
public void setOnItemClickListener(OnItemClickListener l) {
this.mItemClickListener = l;
}
private OnItemLongClickListener mItemLongClickListener;
public void setItemLongClickListener(OnItemLongClickListener l) {
this.mItemLongClickListener = l;
}
}

View File

@ -0,0 +1,14 @@
package com.yuxihan.sdu.ui.home.adapter;
import android.view.View;
import androidx.recyclerview.widget.RecyclerView;
/**
* @authorluck
* @date2020-01-13 17:58
* @describe长按事件
*/
public interface OnItemLongClickListener {
void onItemLongClick(RecyclerView.ViewHolder holder, int position, View v);
}

View File

@ -47,7 +47,11 @@ public class InfoEditViewModel extends ViewModel {
@Override
public void onResponse(Call<DataBean> call, Response<DataBean> response) {
//请求成功返回是一个封装为DataBean的响应
Log.e("TAG", "接口返回内容 ===== " + response.body().getResult());
if (null == response.body()) {
Toast.makeText(SDUApp.getAppContext(), "Internal Server Error",
Toast.LENGTH_LONG).show();
return;
}
if (Const.ERROR_CODE_NORMAL.equals(response.body().getErrCode())) {
updateNicknameState.setValue(new UpdateNicknameState(nickname));
} else {
@ -63,6 +67,7 @@ public class InfoEditViewModel extends ViewModel {
}
});
}
private void updateUserHead(String accessUrl) {
UpdateService updateService = SDUApp.getRetrofit().create(UpdateService.class);
@ -71,7 +76,11 @@ public class InfoEditViewModel extends ViewModel {
@Override
public void onResponse(Call<DataBean> call, Response<DataBean> response) {
//请求成功返回是一个封装为DataBean的响应
Log.e("TAG", "接口返回内容 ===== " + response.body().getResult());
if (null == response.body()) {
Toast.makeText(SDUApp.getAppContext(), "Internal Server Error",
Toast.LENGTH_LONG).show();
return;
}
if (Const.ERROR_CODE_NORMAL.equals(response.body().getErrCode())) {
updateUserHead.setValue(new UpdateUserHeadState(accessUrl));
} else {

View File

@ -1,6 +1,7 @@
package com.yuxihan.sdu.ui.login;
import android.util.Log;
import android.widget.Toast;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
@ -47,13 +48,20 @@ public class LoginViewModel extends ViewModel {
@Override
public void onResponse(Call<DataBean> call, Response<DataBean> response) {
//请求成功返回是一个封装为DataBean的响应
Log.e("TAG", "接口返回内容 ===== " + response.body().getResult());
if (null == response.body()) {
Toast.makeText(SDUApp.getAppContext(), "Internal Server Error",
Toast.LENGTH_LONG).show();
return;
}
if (Const.ERROR_CODE_NORMAL.equals(response.body().getErrCode())) {
String token = response.body().getResult().getToken();
String nickName = response.body().getResult().getNickname();
String userHead = response.body().getResult().getUserHead();
String familyId = response.body().getResult().getFamilyId();
String familyName = response.body().getResult().getFamilyName();
loggedInUser.setValue(new LoggedInUser(username, username));
AccountUtils.saveLoginState(username, token, nickName, userHead);
AccountUtils.saveLoginState(username, token, nickName, userHead, familyId,
familyName);
} else {
loggedInUser.setValue(new LoggedInUser(username, response.body().getErrMsg(),
false));

View File

@ -2,7 +2,6 @@ package com.yuxihan.sdu.ui.reg;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import androidx.lifecycle.LiveData;
@ -47,9 +46,12 @@ public class RegViewModel extends ViewModel {
@Override
public void onResponse(Call<DataBean> call, Response<DataBean> response) {
//请求成功返回是一个封装为DataBean的响应
Log.e("TAG", "接口返回内容 ===== " + response.body().getResult());
if (null == response.body()) {
Toast.makeText(SDUApp.getAppContext(), "Internal Server Error",
Toast.LENGTH_LONG).show();
return;
}
if (Const.ERROR_CODE_NORMAL.equals(response.body().getErrCode())) {
String token = response.body().getResult().getToken();
sendSMSResult.setValue(new SendSMSResult(true));
} else {
Toast.makeText(SDUApp.getAppContext(), response.body().getErrMsg(),
@ -75,9 +77,12 @@ public class RegViewModel extends ViewModel {
@Override
public void onResponse(Call<DataBean> call, Response<DataBean> response) {
//请求成功返回是一个封装为DataBean的响应
Log.e("TAG", "接口返回内容 ===== " + response.body().getResult());
if (null == response.body()) {
Toast.makeText(SDUApp.getAppContext(), "Internal Server Error",
Toast.LENGTH_LONG).show();
return;
}
if (Const.ERROR_CODE_NORMAL.equals(response.body().getErrCode())) {
String token = response.body().getResult().getToken();
loggedInUser.setValue(new LoggedInUser(username, username));
} else {
loggedInUser.setValue(new LoggedInUser(username, response.body().getErrMsg(),

View File

@ -0,0 +1,198 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.home.NewPostActivity">
<RelativeLayout
android:id="@+id/rl_account_title"
android:layout_width="match_parent"
android:layout_height="75dp"
android:gravity="center_vertical"
android:paddingTop="25dp"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/iv_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="14dp"
android:paddingTop="12dp"
android:text="@string/cancel"
android:textColor="@color/text_hint"
android:textSize="15sp" />
<androidx.cardview.widget.CardView
android:layout_width="53dp"
android:layout_height="25dp"
android:layout_alignParentEnd="true"
android:layout_margin="14dp"
android:layout_marginTop="12dp"
android:background="@android:color/white"
app:cardCornerRadius="22dp">
<TextView
android:id="@+id/btn_submit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_submit_btn"
android:enabled="true"
android:gravity="center"
android:text="@string/submit"
android:textColor="@color/white"
android:textSize="15sp" />
</androidx.cardview.widget.CardView>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingStart="30dp"
android:paddingEnd="30dp">
<EditText
android:id="@+id/et_post_text_content"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginBottom="15dp"
android:background="@null"
android:gravity="start"
android:hint="@string/record_baby_things"
android:maxLines="5" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:overScrollMode="never" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="10dp"
android:background="@color/divider_gray" />
<RelativeLayout
android:id="@+id/rl_post_to"
android:layout_width="match_parent"
android:layout_height="50dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/post_to"
android:textColor="@color/black"
android:textSize="12sp" />
<TextView
android:id="@+id/tv_post_to"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toStartOf="@+id/ic_next"
tools:text="家庭名称"
android:textColor="@color/black"
android:textSize="12sp" />
<ImageView
android:id="@+id/ic_next"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_alignParentEnd="true"
android:layout_marginEnd="15dp"
android:src="@drawable/ic_arrow_right" />
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/divider_gray" />
<RelativeLayout
android:id="@+id/rl_select_relate_baby"
android:layout_width="match_parent"
android:layout_height="50dp"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingEnd="15dp"
tools:ignore="RtlSymmetry">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/select_relate_baby"
android:textColor="@color/black"
android:textSize="12sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:text="@string/post_to"
android:textColor="@color/black"
android:textSize="12sp" />
<ImageView
android:id="@+id/ic_next_baby"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_alignParentEnd="true"
android:layout_marginEnd="15dp"
android:src="@drawable/ic_arrow_right"
android:visibility="gone" />
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/divider_gray" />
<RelativeLayout
android:id="@+id/rl_record_time"
android:layout_width="match_parent"
android:layout_height="50dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/record_time"
android:textColor="@color/black"
android:textSize="12sp" />
<TextView
android:id="@+id/tv_record_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toStartOf="@+id/ic_next_time"
tools:text="2020-02-02"
android:textColor="@color/black"
android:textSize="12sp" />
<ImageView
android:id="@+id/ic_next_time"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_alignParentEnd="true"
android:layout_marginEnd="15dp"
android:src="@drawable/ic_arrow_right" />
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/divider_gray" />
</LinearLayout>
</LinearLayout>

View File

@ -17,6 +17,7 @@
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/add_new_post_pic"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginStart="12dp"
@ -31,6 +32,7 @@
android:textSize="20sp" />
<ImageView
android:id="@+id/add_new_post"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentEnd="true"

View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<com.luck.picture.lib.widget.SquareRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:gravity="center_vertical">
<ImageView
android:id="@+id/fiv"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:src="@color/app_color_f6" />
<ImageView
android:id="@+id/iv_del"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/fiv"
android:layout_alignRight="@id/fiv"
android:paddingLeft="10dp"
android:paddingBottom="10dp"
android:scaleType="centerInside"
android:src="@mipmap/ic_delete_menu"
android:visibility="gone"
tools:visibility="visible" />
<TextView
android:id="@+id/tv_duration"
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_alignLeft="@id/fiv"
android:layout_alignRight="@id/fiv"
android:layout_alignBottom="@id/fiv"
android:background="@drawable/picture_icon_shadow_bg"
android:drawableLeft="@drawable/picture_icon_video"
android:drawablePadding="5dp"
android:gravity="center_vertical"
android:paddingLeft="5dp"
android:paddingTop="8dp"
android:text="00:00"
android:textColor="@color/app_color_white"
android:textSize="11sp"
android:visibility="gone"
tools:visibility="visible" />
</com.luck.picture.lib.widget.SquareRelativeLayout>

View File

@ -3,12 +3,16 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="84dp"
android:background="@color/white"
xmlns:tools="http://schemas.android.com/tools"
android:layout_marginBottom="10dp"
android:padding="10dp">
<ImageView
android:id="@+id/iv_home_head"
android:layout_width="41dp"
android:layout_height="41dp"
android:src="@drawable/ic_home"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@ -17,7 +21,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:text="HOMENAME"
tools:text="HOMENAME"
android:textColor="@color/black"
android:textSize="15sp"
app:layout_constraintLeft_toRightOf="@+id/iv_home_head"
@ -32,6 +36,7 @@
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@+id/iv_home_head"
app:layout_constraintLeft_toRightOf="@+id/iv_home_head" />
<TextView
android:id="@+id/tv_creator"
android:layout_width="wrap_content"
@ -42,6 +47,7 @@
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@+id/iv_home_head" />
<ImageView
android:id="@+id/iv_select_status"
android:layout_width="25dp"
@ -50,6 +56,7 @@
android:background="@drawable/ic_selected"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_home_setting"
android:visibility="gone"
@ -59,5 +66,5 @@
android:textSize="15sp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:text="@string/setting"/>
android:text="@string/setting" />
</androidx.constraintlayout.widget.ConstraintLayout>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -38,4 +38,10 @@
<string name="input_code_to_join_home">输入邀请码加入家庭</string>
<string name="submit">提交</string>
<string name="go_get_code">邀请码请找家人获取</string>
<string name="record_baby_things">快记下宝宝成长的点滴吧</string>
<string name="cancel">取消</string>
<string name="post_to">发布到</string>
<string name="select_relate_baby">选择相关宝宝</string>
<string name="record_time">记录时间</string>
<string name="time">时间</string>
</resources>

View File

@ -5,6 +5,7 @@ buildscript {
repositories {
maven { url 'https://maven.aliyun.com/repository/public' }
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://jitpack.io' }
google()
}
dependencies {
@ -19,6 +20,7 @@ allprojects {
repositories {
maven { url 'https://maven.aliyun.com/repository/public' }
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://jitpack.io' }
google()
}
}