ソースを参照

feat: 充值记录列表

master
huting 2年前
コミット
ccf3b9248e
24個のファイルの変更2104行の追加12行の削除
  1. 4
    0
      app/src/main/AndroidManifest.xml
  2. 61
    2
      app/src/main/java/com/huntersun/vkyes/etcopencard/project/dialog/RechargeConfirmDialog.java
  3. 101
    2
      app/src/main/java/com/huntersun/vkyes/etcopencard/project/ui/activity/after/RechargeRecordActivity.java
  4. 24
    1
      app/src/main/java/com/huntersun/vkyes/etcopencard/project/ui/activity/after/TopEntrapmentActivity.java
  5. 175
    0
      app/src/main/java/com/huntersun/vkyes/etcopencard/project/ui/fragment/RechargeRecordFragment.java
  6. 1
    0
      app/src/main/java/com/huntersun/vkyes/etcopencard/project/utils/Constants.java
  7. 160
    0
      app/src/main/java/com/huntersun/vkyes/etcopencard/src/widget/tablayout/MsgView.java
  8. 56
    0
      app/src/main/java/com/huntersun/vkyes/etcopencard/src/widget/tablayout/MyFragmentAdapter.java
  9. 10
    0
      app/src/main/java/com/huntersun/vkyes/etcopencard/src/widget/tablayout/OnTabSelectListener.java
  10. 921
    0
      app/src/main/java/com/huntersun/vkyes/etcopencard/src/widget/tablayout/SlidingTabLayout.java
  11. 53
    0
      app/src/main/java/com/huntersun/vkyes/etcopencard/src/widget/tablayout/UnreadMsgUtils.java
  12. 8
    0
      app/src/main/res/drawable-v1/border_dark_green_radius.xml
  13. 8
    0
      app/src/main/res/drawable-v1/border_dark_grey_radius.xml
  14. 8
    0
      app/src/main/res/drawable-v1/border_grey_white_radius.xml
  15. 173
    0
      app/src/main/res/layout-v3/item_recharge_record.xml
  16. 3
    2
      app/src/main/res/layout/activity_qc_step1.xml
  17. 150
    2
      app/src/main/res/layout/activity_recharge_record.xml
  18. 68
    3
      app/src/main/res/layout/dialog_recharge_confirm.xml
  19. 27
    0
      app/src/main/res/layout/fragment_recharge_record.xml
  20. 31
    0
      app/src/main/res/layout/layout_tab.xml
  21. バイナリ
      app/src/main/res/mipmap-xhdpi/icon_date.png
  22. バイナリ
      app/src/main/res/mipmap-xhdpi/icon_down_grey.png
  23. 60
    0
      app/src/main/res/values/styles.xml
  24. 2
    0
      library/base/src/main/res/values/colors.xml

+ 4
- 0
app/src/main/AndroidManifest.xml ファイルの表示

@@ -320,6 +320,10 @@
<activity android:name=".project.ui.activity.mail.InfoTabActivity"
android:launchMode="singleTop"
android:screenOrientation="portrait" />
<!-- 充值记录 -->
<activity android:name=".project.ui.activity.after.RechargeRecordActivity"
android:launchMode="singleTop"
android:screenOrientation="portrait" />
</application>

</manifest>

+ 61
- 2
app/src/main/java/com/huntersun/vkyes/etcopencard/project/dialog/RechargeConfirmDialog.java ファイルの表示

@@ -1,6 +1,65 @@
package com.huntersun.vkyes.etcopencard.project.dialog;

import android.app.Activity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.hjq.base.BaseDialog;
import com.huntersun.vkyes.etcopencard.R;

/**
* Date :2023-03-13
* Description:
*/ class RechargeConfirmDialog {
* Description:充值金额选择弹窗
*/
public class RechargeConfirmDialog {
public static final class Builder extends BaseDialog.Builder<Builder> {
private TextView tvPayMoney;
private TextView tvBalance;
private Button btnRecharge;

private InOnConfirmClick inOnConfirmClick;

public Builder(Activity activity) {
super(activity);
setContentView(R.layout.dialog_recharge_confirm);

tvPayMoney = findViewById(R.id.pay_money);
tvBalance = findViewById(R.id.balance);
btnRecharge = findViewById(R.id.btn_recharge);

btnRecharge.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(inOnConfirmClick != null){
inOnConfirmClick.onConfirmClick();
}
}
});
}

/*
* 设置回调监听器
*/
public Builder setListener(InOnConfirmClick listener) {
inOnConfirmClick = listener;
return this;
}

/*
* 设置显示内容
* @param payMoney
* @param balance
* @return
*/
public Builder setContent(String payMoney,String balance) {
tvPayMoney.setText("¥ " + payMoney);
tvBalance.setText("¥ " + balance);
return this;
}
}

public interface InOnConfirmClick{
void onConfirmClick();
}
}

+ 101
- 2
app/src/main/java/com/huntersun/vkyes/etcopencard/project/ui/activity/after/RechargeRecordActivity.java ファイルの表示

@@ -1,6 +1,105 @@
package com.huntersun.vkyes.etcopencard.project.ui.activity.after;

import android.view.View;

import com.huntersun.vkyes.etcopencard.databinding.ActivityAuditingBinding;
import com.huntersun.vkyes.etcopencard.databinding.ActivityRechargeRecordBinding;
import com.huntersun.vkyes.etcopencard.project.ui.fragment.FragmentSonOne;
import com.huntersun.vkyes.etcopencard.project.ui.fragment.RechargeRecordFragment;
import com.huntersun.vkyes.etcopencard.src.app.AppActivity;
import com.huntersun.vkyes.etcopencard.src.widget.tablayout.MyFragmentAdapter;
import com.huntersun.vkyes.etcopencard.src.widget.tablayout.OnTabSelectListener;

import java.util.ArrayList;
import java.util.List;

import androidx.fragment.app.Fragment;

/**
* Date :2023-03-13
* Description:
*/ class RechargeRecordActivity {
* Description:充值记录
*/
public class RechargeRecordActivity extends AppActivity implements OnTabSelectListener {
private ActivityRechargeRecordBinding binding;

private MyFragmentAdapter mAdapter;
private ArrayList<Fragment> mFragments = new ArrayList<>();
private List<String> mTitles = new ArrayList<>();

//0-全部 1-半条流水 2-圈存成功 3-退款中 4-撤销中
private int type = 0;

@Override
protected View getLayoutView() {
binding = ActivityRechargeRecordBinding.inflate(getLayoutInflater());
return binding.getRoot();
}

@Override
protected void initView() {
initTabLayout();
initClick();
}

@Override
protected void initData() {

}

/*
* 初始化TabLayout
*/
private void initTabLayout(){
mTitles.add("全部");
mTitles.add("半条流水");
mTitles.add("圈存成功");
mTitles.add("退款中");
mTitles.add("撤销中");

mFragments.add(RechargeRecordFragment.newInstance("0"));
mFragments.add(RechargeRecordFragment.newInstance("1"));
mFragments.add(RechargeRecordFragment.newInstance("2"));
mFragments.add(RechargeRecordFragment.newInstance("3"));
mFragments.add(RechargeRecordFragment.newInstance("4"));

mAdapter = new MyFragmentAdapter(getSupportFragmentManager(),mFragments,mTitles);
binding.viewpager.setAdapter(mAdapter);
binding.tabTitle.setViewPager( binding.viewpager);
binding.tabTitle.setOnTabSelectListener(this);
binding.viewpager.setCurrentItem(type);
binding.viewpager.setOffscreenPageLimit(mFragments.size());
}

@Override
public void onTabSelect(int position) {

}

@Override
public void onTabReselect(int position) {

}

private void initClick(){
binding.llTime.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
toast("选择时间");
}
});

binding.llPayType.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
toast("选择支付方式");
}
});

binding.btnCheck.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
toast("查询" + binding.etSearch.getText().toString());
}
});
}
}

+ 24
- 1
app/src/main/java/com/huntersun/vkyes/etcopencard/project/ui/activity/after/TopEntrapmentActivity.java ファイルの表示

@@ -8,6 +8,8 @@ import android.view.View;
import android.widget.EditText;

import com.google.gson.Gson;
import com.hjq.umeng.Platform;
import com.hjq.umeng.UmengShare;
import com.huntersun.vky.obublelib.box.BoxManagers;
import com.huntersun.vkyes.etcopencard.R;
import com.huntersun.vkyes.etcopencard.databinding.ActivityToEntrapmentBinding;
@@ -20,11 +22,15 @@ import com.huntersun.vkyes.etcopencard.project.api.bean.IFCode;
import com.huntersun.vkyes.etcopencard.project.api.bean.RechargeBean;
import com.huntersun.vkyes.etcopencard.project.api.bean.ResultBean;
import com.huntersun.vkyes.etcopencard.project.api.bean.SendTheVerificationCodeBean;
import com.huntersun.vkyes.etcopencard.project.dialog.RechargeConfirmDialog;
import com.huntersun.vkyes.etcopencard.project.tool.EquipmentAndTools;
import com.huntersun.vkyes.etcopencard.project.ui.adapter.RechargeAdapter;
import com.huntersun.vkyes.etcopencard.project.ui.adapter.interfaces.INRechargeChoose;
import com.huntersun.vkyes.etcopencard.src.aop.SingleClick;
import com.huntersun.vkyes.etcopencard.src.app.AppActivity;
import com.huntersun.vkyes.etcopencard.src.ui.dialog.ShareDialog;
import com.umeng.socialize.media.UMImage;
import com.umeng.socialize.media.UMWeb;

import java.util.ArrayList;
import java.util.List;
@@ -117,6 +123,11 @@ public class TopEntrapmentActivity extends AppActivity implements INRechargeChoo
@Override
@SingleClick
public void onClick(View v) {
UMWeb content = new UMWeb("https://github.com/getActivity/AndroidProject");
content.setTitle("Github");
content.setThumb(new UMImage(TopEntrapmentActivity.this, R.mipmap.launcher_ic));
content.setDescription(getString(R.string.app_name));

if (!TextUtils.isEmpty(binding.buttomSex.getText())) {
licensePlateColor = Double.parseDouble(binding.buttomSex.getText() + "");
// if ((licensePlateColor % 10 != 0)) {
@@ -206,6 +217,7 @@ public class TopEntrapmentActivity extends AppActivity implements INRechargeChoo
});
}


//充值检测
public void rechargeDetection(Callback callback) {
SendTheVerificationCodeBean bean = new SendTheVerificationCodeBean();
@@ -447,6 +459,17 @@ public class TopEntrapmentActivity extends AppActivity implements INRechargeChoo
@Override
public void chooseRechargeMoney(RechargeBean rechargeBean) {
this.moneyInfo = rechargeBean;
toast(moneyInfo.payMoney);
//toast(moneyInfo.payMoney);
//TODO 测试
jumpToPage(RechargeRecordActivity.class);
// 确认充值对话框
/*new RechargeConfirmDialog.Builder(TopEntrapmentActivity.this)
.setContent("159.00","1200")
.setListener(new RechargeConfirmDialog.InOnConfirmClick() {
@Override
public void onConfirmClick() {
toast("确认充值");
}
}) .show();*/
}
}

+ 175
- 0
app/src/main/java/com/huntersun/vkyes/etcopencard/project/ui/fragment/RechargeRecordFragment.java ファイルの表示

@@ -0,0 +1,175 @@
package com.huntersun.vkyes.etcopencard.project.ui.fragment;

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

import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.google.gson.Gson;
import com.huntersun.vkyes.etcopencard.R;
import com.huntersun.vkyes.etcopencard.databinding.FragmentRechargeRecordBinding;
import com.huntersun.vkyes.etcopencard.project.api.Api;
import com.huntersun.vkyes.etcopencard.project.api.Converter;
import com.huntersun.vkyes.etcopencard.project.api.MyRetrofit;
import com.huntersun.vkyes.etcopencard.project.api.Parameters;
import com.huntersun.vkyes.etcopencard.project.api.RequestParameters;
import com.huntersun.vkyes.etcopencard.project.api.Result;
import com.huntersun.vkyes.etcopencard.project.api.bean.IFCode;
import com.huntersun.vkyes.etcopencard.project.api.bean.ResultBean;
import com.huntersun.vkyes.etcopencard.project.ui.activity.after.RechargeRecordActivity;
import com.huntersun.vkyes.etcopencard.project.utils.Constants;
import com.huntersun.vkyes.etcopencard.src.action.StatusAction;
import com.huntersun.vkyes.etcopencard.src.app.AppFragment;
import com.huntersun.vkyes.etcopencard.src.app.TitleBarFragment;
import com.huntersun.vkyes.etcopencard.src.widget.StatusLayout;
import com.scwang.smart.refresh.layout.api.RefreshLayout;
import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener;

import org.jetbrains.annotations.NotNull;

import androidx.annotation.NonNull;
import retrofit2.Response;

/**
* Date :2023-03-13
* Description:充值记录fragment
*/
public class RechargeRecordFragment extends TitleBarFragment<RechargeRecordActivity> implements OnRefreshLoadMoreListener, StatusAction {
private FragmentRechargeRecordBinding binding;

//当前类型
private String curType = "0";
private int page = 1;

public static AppFragment<RechargeRecordActivity> newInstance(String type) {
return new RechargeRecordFragment(type);
}

public RechargeRecordFragment(String curType) {
this.curType = curType;
}

@Override
protected View getLayoutView(LayoutInflater inflater, ViewGroup container) {
binding = FragmentRechargeRecordBinding.inflate(inflater, container, false);
return binding.getRoot();
}

@Override
protected void initView() {
binding.recycler.setAdapter(adapter);
binding.rlStatusRefresh.setOnRefreshLoadMoreListener(this);
binding.rlStatusRefresh.setOnRefreshListener(this);
}

@Override
protected void initData() {
showLoading();
LoadData();
}

@Override
public StatusLayout getStatusLayout() {
return binding.hlStatusHint;
}

@Override
public void onLoadMore(@NonNull @NotNull RefreshLayout refreshLayout) {
postDelayed(() -> {
page = page + 1;
LoadData();
binding.rlStatusRefresh.finishLoadMore();
}, 1000);
}

@Override
public void onRefresh(@NonNull @NotNull RefreshLayout refreshLayout) {
postDelayed(() -> {
page = 1;
LoadData();
binding.rlStatusRefresh.finishRefresh();
}, 1000);
}

private void LoadData(){
Parameters parameters = new Parameters();
parameters.setTabIndex("0");
parameters.setPageNo(String.valueOf(page));
parameters.setPageSize(Constants.pageSize);
parameters.setVehiclePlate("");
RequestParameters parameters1 =
new RequestParameters(IFCode.IFCODE36, new Gson().toJson(parameters));
if (page == 1) {
showLoading();
}

new MyRetrofit().getRetrofit().create(Api.class).message2(parameters1)
.enqueue(new Converter<Result>(getActivity()) {
@SuppressLint("NotifyDataSetChanged")
@Override
protected void onSuccess(ResultBean resultBean, ResultBean.BizContent bizContent1) {
if (bizContent1.getData() == null) {
postDelayed(RechargeRecordFragment.this::showEmpty, 300);
}
if (page == 1) {
adapter.replaceData(bizContent1.getData());
} else {
adapter.addData(bizContent1.getData());
}
if (bizContent1.getData().size() == 0 && page == 1) {
postDelayed(RechargeRecordFragment.this::showEmpty, 300);
} else {
postDelayed(RechargeRecordFragment.this::showComplete, 300);
}
}

@Override
public void onError(String err, Response<Result> resp) {
super.onError(err, resp);
showError(new StatusLayout.OnRetryListener() {
@Override
public void onRetry(StatusLayout layout) {
LoadData();
}
});
}
});
}

BaseQuickAdapter<ResultBean.BizContent, BaseViewHolder> adapter = new BaseQuickAdapter<ResultBean.BizContent, BaseViewHolder>(R.layout.item_recharge_record) {
@Override
protected void convert(BaseViewHolder holder, ResultBean.BizContent item) {
holder.setText(R.id.tvOrderId,"20230010330");
holder.setText(R.id.tvOrderStatus,"退款中");
holder.setText(R.id.tvQcId,"01872753475754");
holder.setText(R.id.tvEtcNum,"20230112156230");
holder.setText(R.id.tvType,"储值卡圈存");
holder.setText(R.id.tvTime,"2022-23-23");
holder.setText(R.id.tvMoney,"" + "100.00");
holder.setText(R.id.tvPayType,"¥" + "微信");

holder.setTextColor(R.id.tvOrderStatus,getResources().getColor(R.color.common_accent_color));
//holder.setTextColor(R.id.tvOrderStatus,getResources().getColor(R.color.color_FF8000));
holder.setText(R.id.btnGrey,"撤销圈存"); //申请退款、查看进度、撤销圈存
holder.setText(R.id.btnGreen,"圈存修复");

holder.setOnClickListener(R.id.btnGrey, new View.OnClickListener() {
@Override
public void onClick(View view) {
toast("撤销圈存");
}
});

holder.setOnClickListener(R.id.btnGreen, new View.OnClickListener() {
@Override
public void onClick(View view) {
toast("圈存修复");
}
});
}
};


}

+ 1
- 0
app/src/main/java/com/huntersun/vkyes/etcopencard/project/utils/Constants.java ファイルの表示

@@ -5,6 +5,7 @@ package com.huntersun.vkyes.etcopencard.project.utils;
* Description:常量
*/
public class Constants {
public static final String pageSize = "10";

//******************************订单状态********************************//


+ 160
- 0
app/src/main/java/com/huntersun/vkyes/etcopencard/src/widget/tablayout/MsgView.java ファイルの表示

@@ -0,0 +1,160 @@
package com.huntersun.vkyes.etcopencard.src.widget.tablayout;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.StateListDrawable;
import android.os.Build;
import android.util.AttributeSet;

import com.huntersun.vkyes.etcopencard.R;

/**
* Date :2023-03-13
* Description:
*/
public class MsgView extends androidx.appcompat.widget.AppCompatTextView {
private Context context;
private GradientDrawable gd_background = new GradientDrawable();
private int backgroundColor;
private int cornerRadius;
private int strokeWidth;
private int strokeColor;
private boolean isRadiusHalfHeight;
private boolean isWidthHeightEqual;

public MsgView(Context context) {
this(context, null);
}

public MsgView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public MsgView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.context = context;
obtainAttributes(context, attrs);
}

private void obtainAttributes(Context context, AttributeSet attrs) {
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MsgView);
backgroundColor = ta.getColor(R.styleable.MsgView_mv_backgroundColor, Color.TRANSPARENT);
cornerRadius = ta.getDimensionPixelSize(R.styleable.MsgView_mv_cornerRadius, 0);
strokeWidth = ta.getDimensionPixelSize(R.styleable.MsgView_mv_strokeWidth, 0);
strokeColor = ta.getColor(R.styleable.MsgView_mv_strokeColor, Color.TRANSPARENT);
isRadiusHalfHeight = ta.getBoolean(R.styleable.MsgView_mv_isRadiusHalfHeight, false);
isWidthHeightEqual = ta.getBoolean(R.styleable.MsgView_mv_isWidthHeightEqual, false);

ta.recycle();
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (isWidthHeightEqual() && getWidth() > 0 && getHeight() > 0) {
int max = Math.max(getWidth(), getHeight());
int measureSpec = MeasureSpec.makeMeasureSpec(max, MeasureSpec.EXACTLY);
super.onMeasure(measureSpec, measureSpec);
return;
}

super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (isRadiusHalfHeight()) {
setCornerRadius(getHeight() / 2);
} else {
setBgSelector();
}
}


public void setBackgroundColor(int backgroundColor) {
this.backgroundColor = backgroundColor;
setBgSelector();
}

public void setCornerRadius(int cornerRadius) {
this.cornerRadius = dp2px(cornerRadius);
setBgSelector();
}

public void setStrokeWidth(int strokeWidth) {
this.strokeWidth = dp2px(strokeWidth);
setBgSelector();
}

public void setStrokeColor(int strokeColor) {
this.strokeColor = strokeColor;
setBgSelector();
}

public void setIsRadiusHalfHeight(boolean isRadiusHalfHeight) {
this.isRadiusHalfHeight = isRadiusHalfHeight;
setBgSelector();
}

public void setIsWidthHeightEqual(boolean isWidthHeightEqual) {
this.isWidthHeightEqual = isWidthHeightEqual;
setBgSelector();
}

public int getBackgroundColor() {
return backgroundColor;
}

public int getCornerRadius() {
return cornerRadius;
}

public int getStrokeWidth() {
return strokeWidth;
}

public int getStrokeColor() {
return strokeColor;
}

public boolean isRadiusHalfHeight() {
return isRadiusHalfHeight;
}

public boolean isWidthHeightEqual() {
return isWidthHeightEqual;
}

protected int dp2px(float dp) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dp * scale + 0.5f);
}

protected int sp2px(float sp) {
final float scale = this.context.getResources().getDisplayMetrics().scaledDensity;
return (int) (sp * scale + 0.5f);
}

private void setDrawable(GradientDrawable gd, int color, int strokeColor) {
gd.setColor(color);
gd.setCornerRadius(cornerRadius);
gd.setStroke(strokeWidth, strokeColor);
}

public void setBgSelector() {
StateListDrawable bg = new StateListDrawable();

setDrawable(gd_background, backgroundColor, strokeColor);
bg.addState(new int[]{-android.R.attr.state_pressed}, gd_background);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {//16
setBackground(bg);
} else {
//noinspection deprecation
setBackgroundDrawable(bg);
}
}

}

+ 56
- 0
app/src/main/java/com/huntersun/vkyes/etcopencard/src/widget/tablayout/MyFragmentAdapter.java ファイルの表示

@@ -0,0 +1,56 @@
package com.huntersun.vkyes.etcopencard.src.widget.tablayout;

import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.List;

import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;

/**
* Date :2023-03-13
* Description:Fragment adapter
*/
public class MyFragmentAdapter extends FragmentPagerAdapter {

private List<Fragment> fragments = new ArrayList<>();
private List<String> fragmentTitles = new ArrayList<>();

public MyFragmentAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments=fragments;
}

public MyFragmentAdapter(FragmentManager fm, List<Fragment> fragments,
List<String> fragmentTitles) {
super(fm);
this.fragments = fragments;
this.fragmentTitles = fragmentTitles;
}

@Override
public Fragment getItem(int position) {
return fragments.get(position);
}

@Override
public int getCount() {
return fragments.size();
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
super.destroyItem(container, position, object);
}

@Override
public CharSequence getPageTitle(int position) {
if (fragmentTitles != null) {
return fragmentTitles.get(position);
} else {
return "";
}
}
}

+ 10
- 0
app/src/main/java/com/huntersun/vkyes/etcopencard/src/widget/tablayout/OnTabSelectListener.java ファイルの表示

@@ -0,0 +1,10 @@
package com.huntersun.vkyes.etcopencard.src.widget.tablayout;

/**
* Date :2023-03-13
* Description:TabLayout切换监听
*/
public interface OnTabSelectListener {
void onTabSelect(int position);
void onTabReselect(int position);
}

+ 921
- 0
app/src/main/java/com/huntersun/vkyes/etcopencard/src/widget/tablayout/SlidingTabLayout.java ファイルの表示

@@ -0,0 +1,921 @@
package com.huntersun.vkyes.etcopencard.src.widget.tablayout;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.huntersun.vkyes.etcopencard.R;
import com.huntersun.vkyes.etcopencard.src.widget.tablayout.MsgView;

import java.util.ArrayList;
import java.util.Collections;

import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;

/**
* Date :2023-03-13
* Description:自定义tabLayout
*/
public class SlidingTabLayout extends HorizontalScrollView implements ViewPager.OnPageChangeListener{
private Context mContext;
private ViewPager mViewPager;
private ArrayList<String> mTitles;
private LinearLayout mTabsContainer;
private int mCurrentTab;
private float mCurrentPositionOffset;
private int mTabCount;
/** 用于绘制显示器 */
private Rect mIndicatorRect = new Rect();
/** 用于实现滚动居中 */
private Rect mTabRect = new Rect();
private GradientDrawable mIndicatorDrawable = new GradientDrawable();

private Paint mRectPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint mDividerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint mTrianglePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Path mTrianglePath = new Path();
private static final int STYLE_NORMAL = 0;
private static final int STYLE_TRIANGLE = 1;
private static final int STYLE_BLOCK = 2;
private int mIndicatorStyle = STYLE_NORMAL;

private float mTabPadding;
private boolean mTabSpaceEqual;
private float mTabWidth;

/** indicator */
private int mIndicatorColor;
private float mIndicatorHeight;
private float mIndicatorWidth;
private float mIndicatorCornerRadius;
private float mIndicatorMarginLeft;
private float mIndicatorMarginTop;
private float mIndicatorMarginRight;
private float mIndicatorMarginBottom;
private int mIndicatorGravity;
private boolean mIndicatorWidthEqualTitle;

/** underline */
private int mUnderlineColor;
private float mUnderlineHeight;
private int mUnderlineGravity;

/** divider */
private int mDividerColor;
private float mDividerWidth;
private float mDividerPadding;

/** title */
private static final int TEXT_BOLD_NONE = 0;
private static final int TEXT_BOLD_WHEN_SELECT = 1;
private static final int TEXT_BOLD_BOTH = 2;
private float mTextsize;
private int mTextSelectColor;
private int mTextUnselectColor;
private int mTextBold;
private boolean mTextAllCaps;

private int mLastScrollX;
private int mHeight;
private boolean mSnapOnTabClick;

public SlidingTabLayout(Context context) {
this(context, null, 0);
}

public SlidingTabLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public SlidingTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setFillViewport(true);//设置滚动视图是否可以伸缩其内容以填充视口
setWillNotDraw(false);//重写onDraw方法,需要调用这个方法来清除flag
setClipChildren(false);
setClipToPadding(false);

this.mContext = context;
mTabsContainer = new LinearLayout(context);
addView(mTabsContainer);

obtainAttributes(context, attrs);

//get layout_height
String height = attrs.getAttributeValue("http://schemas.android.com/apk/res/android", "layout_height");

if (height.equals(ViewGroup.LayoutParams.MATCH_PARENT + "")) {
} else if (height.equals(ViewGroup.LayoutParams.WRAP_CONTENT + "")) {
} else {
int[] systemAttrs = {android.R.attr.layout_height};
TypedArray a = context.obtainStyledAttributes(attrs, systemAttrs);
mHeight = a.getDimensionPixelSize(0, ViewGroup.LayoutParams.WRAP_CONTENT);
a.recycle();
}
}

private void obtainAttributes(Context context, AttributeSet attrs) {
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.SlidingTabLayoutAttr);

mIndicatorStyle = ta.getInt(R.styleable.SlidingTabLayoutAttr_indicator_style, STYLE_NORMAL);
mIndicatorColor = ta.getColor(R.styleable.SlidingTabLayoutAttr_indicator_color, Color.parseColor(mIndicatorStyle == STYLE_BLOCK ? "#4B6A87" : "#ffffff"));
mIndicatorHeight = ta.getDimension(R.styleable.SlidingTabLayoutAttr_indicator_height,
dp2px(mIndicatorStyle == STYLE_TRIANGLE ? 4 : (mIndicatorStyle == STYLE_BLOCK ? -1 : 2)));
mIndicatorWidth = ta.getDimension(R.styleable.SlidingTabLayoutAttr_indicator_width, dp2px(mIndicatorStyle == STYLE_TRIANGLE ? 10 : -1));
mIndicatorCornerRadius = ta.getDimension(R.styleable.SlidingTabLayoutAttr_indicator_corner_radius, dp2px(mIndicatorStyle == STYLE_BLOCK ? -1 : 0));
mIndicatorMarginLeft = ta.getDimension(R.styleable.SlidingTabLayoutAttr_indicator_margin_left, dp2px(0));
mIndicatorMarginTop = ta.getDimension(R.styleable.SlidingTabLayoutAttr_indicator_margin_top, dp2px(mIndicatorStyle == STYLE_BLOCK ? 7 : 0));
mIndicatorMarginRight = ta.getDimension(R.styleable.SlidingTabLayoutAttr_indicator_margin_right, dp2px(0));
mIndicatorMarginBottom = ta.getDimension(R.styleable.SlidingTabLayoutAttr_indicator_margin_bottom, dp2px(mIndicatorStyle == STYLE_BLOCK ? 7 : 0));
mIndicatorGravity = ta.getInt(R.styleable.SlidingTabLayoutAttr_indicator_gravity, Gravity.BOTTOM);
mIndicatorWidthEqualTitle = ta.getBoolean(R.styleable.SlidingTabLayoutAttr_indicator_width_equal_title, false);

mUnderlineColor = ta.getColor(R.styleable.SlidingTabLayoutAttr_underline_color, Color.parseColor("#ffffff"));
mUnderlineHeight = ta.getDimension(R.styleable.SlidingTabLayoutAttr_underline_height, dp2px(0));
mUnderlineGravity = ta.getInt(R.styleable.SlidingTabLayoutAttr_underline_gravity, Gravity.BOTTOM);

mDividerColor = ta.getColor(R.styleable.SlidingTabLayoutAttr_divider_color, Color.parseColor("#ffffff"));
mDividerWidth = ta.getDimension(R.styleable.SlidingTabLayoutAttr_divider_width, dp2px(0));
mDividerPadding = ta.getDimension(R.styleable.SlidingTabLayoutAttr_divider_padding, dp2px(12));

mTextsize = ta.getDimension(R.styleable.SlidingTabLayoutAttr_textsize, sp2px(14));
mTextSelectColor = ta.getColor(R.styleable.SlidingTabLayoutAttr_textSelectColor, Color.parseColor("#ffffff"));
mTextUnselectColor = ta.getColor(R.styleable.SlidingTabLayoutAttr_textUnselectColor, Color.parseColor("#AAffffff"));
mTextBold = ta.getInt(R.styleable.SlidingTabLayoutAttr_textBold, TEXT_BOLD_NONE);
mTextAllCaps = ta.getBoolean(R.styleable.SlidingTabLayoutAttr_textAllCaps, false);

mTabSpaceEqual = ta.getBoolean(R.styleable.SlidingTabLayoutAttr_tab_space_equal, false);
mTabWidth = ta.getDimension(R.styleable.SlidingTabLayoutAttr_tab_width, dp2px(-1));
mTabPadding = ta.getDimension(R.styleable.SlidingTabLayoutAttr_tab_padding, mTabSpaceEqual || mTabWidth > 0 ? dp2px(0) : dp2px(20));

ta.recycle();
}

/** 关联ViewPager */
public void setViewPager(ViewPager vp) {
if (vp == null || vp.getAdapter() == null) {
throw new IllegalStateException("ViewPager or ViewPager adapter can not be NULL !");
}

this.mViewPager = vp;

this.mViewPager.removeOnPageChangeListener(this);
this.mViewPager.addOnPageChangeListener(this);
notifyDataSetChanged();
}

/** 关联ViewPager,用于不想在ViewPager适配器中设置titles数据的情况 */
public void setViewPager(ViewPager vp, String[] titles) {
if (vp == null || vp.getAdapter() == null) {
throw new IllegalStateException("ViewPager or ViewPager adapter can not be NULL !");
}

if (titles == null || titles.length == 0) {
throw new IllegalStateException("Titles can not be EMPTY !");
}

if (titles.length != vp.getAdapter().getCount()) {
throw new IllegalStateException("Titles length must be the same as the page count !");
}

this.mViewPager = vp;
mTitles = new ArrayList<>();
Collections.addAll(mTitles, titles);

this.mViewPager.removeOnPageChangeListener(this);
this.mViewPager.addOnPageChangeListener(this);
notifyDataSetChanged();
}

/** 关联ViewPager,用于连适配器都不想自己实例化的情况 */
public void setViewPager(ViewPager vp, String[] titles, FragmentActivity fa, ArrayList<Fragment> fragments) {
if (vp == null) {
throw new IllegalStateException("ViewPager can not be NULL !");
}

if (titles == null || titles.length == 0) {
throw new IllegalStateException("Titles can not be EMPTY !");
}

this.mViewPager = vp;
this.mViewPager.setAdapter(new InnerPagerAdapter(fa.getSupportFragmentManager(), fragments, titles));

this.mViewPager.removeOnPageChangeListener(this);
this.mViewPager.addOnPageChangeListener(this);
notifyDataSetChanged();
}

/** 更新数据 */
public void notifyDataSetChanged() {
mTabsContainer.removeAllViews();
this.mTabCount = mTitles == null ? mViewPager.getAdapter().getCount() : mTitles.size();
View tabView;
for (int i = 0; i < mTabCount; i++) {
tabView = View.inflate(mContext, R.layout.layout_tab, null);
CharSequence pageTitle = mTitles == null ? mViewPager.getAdapter().getPageTitle(i) : mTitles.get(i);
addTab(i, pageTitle.toString(), tabView);
}

updateTabStyles();
}

public void addNewTab(String title) {
View tabView = View.inflate(mContext, R.layout.layout_tab, null);
if (mTitles != null) {
mTitles.add(title);
}

CharSequence pageTitle = mTitles == null ? mViewPager.getAdapter().getPageTitle(mTabCount) : mTitles.get(mTabCount);
addTab(mTabCount, pageTitle.toString(), tabView);
this.mTabCount = mTitles == null ? mViewPager.getAdapter().getCount() : mTitles.size();

updateTabStyles();
}

/** 创建并添加tab */
private void addTab(final int position, String title, View tabView) {
TextView tv_tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);
if (tv_tab_title != null) {
if (title != null) tv_tab_title.setText(title);
}

tabView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
int position = mTabsContainer.indexOfChild(v);
if (position != -1) {
if (mViewPager.getCurrentItem() != position) {
if (mSnapOnTabClick) {
mViewPager.setCurrentItem(position, false);
} else {
mViewPager.setCurrentItem(position);
}

if (mListener != null) {
mListener.onTabSelect(position);
}
} else {
if (mListener != null) {
mListener.onTabReselect(position);
}
}
}
}
});

/** 每一个Tab的布局参数 */
LinearLayout.LayoutParams lp_tab = mTabSpaceEqual ?
new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f) :
new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
if (mTabWidth > 0) {
lp_tab = new LinearLayout.LayoutParams((int) mTabWidth, LayoutParams.MATCH_PARENT);
}

mTabsContainer.addView(tabView, position, lp_tab);
}

private void updateTabStyles() {
for (int i = 0; i < mTabCount; i++) {
View v = mTabsContainer.getChildAt(i);
// v.setPadding((int) mTabPadding, v.getPaddingTop(), (int) mTabPadding, v.getPaddingBottom());
TextView tv_tab_title = (TextView) v.findViewById(R.id.tv_tab_title);
if (tv_tab_title != null) {
tv_tab_title.setTextColor(i == mCurrentTab ? mTextSelectColor : mTextUnselectColor);
tv_tab_title.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextsize);
tv_tab_title.setPadding((int) mTabPadding, 0, (int) mTabPadding, 0);
if (mTextAllCaps) {
tv_tab_title.setText(tv_tab_title.getText().toString().toUpperCase());
}

if (mTextBold == TEXT_BOLD_BOTH) {
tv_tab_title.getPaint().setFakeBoldText(true);
} else if (mTextBold == TEXT_BOLD_NONE) {
tv_tab_title.getPaint().setFakeBoldText(false);
}
}
}
}

@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
/**
* position:当前View的位置
* mCurrentPositionOffset:当前View的偏移量比例.[0,1)
*/
this.mCurrentTab = position;
this.mCurrentPositionOffset = positionOffset;
scrollToCurrentTab();
invalidate();
}

@Override
public void onPageSelected(int position) {
updateTabSelection(position);
}

@Override
public void onPageScrollStateChanged(int state) {
}

/** HorizontalScrollView滚到当前tab,并且居中显示 */
private void scrollToCurrentTab() {
if (mTabCount <= 0) {
return;
}

int offset = (int) (mCurrentPositionOffset * mTabsContainer.getChildAt(mCurrentTab).getWidth());
/**当前Tab的left+当前Tab的Width乘以positionOffset*/
int newScrollX = mTabsContainer.getChildAt(mCurrentTab).getLeft() + offset;

if (mCurrentTab > 0 || offset > 0) {
/**HorizontalScrollView移动到当前tab,并居中*/
newScrollX -= getWidth() / 2 - getPaddingLeft();
calcIndicatorRect();
newScrollX += ((mTabRect.right - mTabRect.left) / 2);
}

if (newScrollX != mLastScrollX) {
mLastScrollX = newScrollX;
/** scrollTo(int x,int y):x,y代表的不是坐标点,而是偏移量
* x:表示离起始位置的x水平方向的偏移量
* y:表示离起始位置的y垂直方向的偏移量
*/
scrollTo(newScrollX, 0);
}
}

private void updateTabSelection(int position) {
for (int i = 0; i < mTabCount; ++i) {
View tabView = mTabsContainer.getChildAt(i);
final boolean isSelect = i == position;
TextView tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);

if (tab_title != null) {
tab_title.setTextColor(isSelect ? mTextSelectColor : mTextUnselectColor);
if (mTextBold == TEXT_BOLD_WHEN_SELECT) {
tab_title.getPaint().setFakeBoldText(isSelect);
}
}
}
}

private float margin;

private void calcIndicatorRect() {
View currentTabView = mTabsContainer.getChildAt(this.mCurrentTab);
float left = currentTabView.getLeft();
float right = currentTabView.getRight();

//for mIndicatorWidthEqualTitle
if (mIndicatorStyle == STYLE_NORMAL && mIndicatorWidthEqualTitle) {
TextView tab_title = (TextView) currentTabView.findViewById(R.id.tv_tab_title);
mTextPaint.setTextSize(mTextsize);
float textWidth = mTextPaint.measureText(tab_title.getText().toString());
margin = (right - left - textWidth) / 2;
}

if (this.mCurrentTab < mTabCount - 1) {
View nextTabView = mTabsContainer.getChildAt(this.mCurrentTab + 1);
float nextTabLeft = nextTabView.getLeft();
float nextTabRight = nextTabView.getRight();

left = left + mCurrentPositionOffset * (nextTabLeft - left);
right = right + mCurrentPositionOffset * (nextTabRight - right);

//for mIndicatorWidthEqualTitle
if (mIndicatorStyle == STYLE_NORMAL && mIndicatorWidthEqualTitle) {
TextView next_tab_title = (TextView) nextTabView.findViewById(R.id.tv_tab_title);
mTextPaint.setTextSize(mTextsize);
float nextTextWidth = mTextPaint.measureText(next_tab_title.getText().toString());
float nextMargin = (nextTabRight - nextTabLeft - nextTextWidth) / 2;
margin = margin + mCurrentPositionOffset * (nextMargin - margin);
}
}

mIndicatorRect.left = (int) left;
mIndicatorRect.right = (int) right;
//for mIndicatorWidthEqualTitle
if (mIndicatorStyle == STYLE_NORMAL && mIndicatorWidthEqualTitle) {
mIndicatorRect.left = (int) (left + margin - 1);
mIndicatorRect.right = (int) (right - margin - 1);
}

mTabRect.left = (int) left;
mTabRect.right = (int) right;

if (mIndicatorWidth < 0) { //indicatorWidth小于0时,原jpardogo's PagerSlidingTabStrip

} else {//indicatorWidth大于0时,圆角矩形以及三角形
float indicatorLeft = currentTabView.getLeft() + (currentTabView.getWidth() - mIndicatorWidth) / 2;

if (this.mCurrentTab < mTabCount - 1) {
View nextTab = mTabsContainer.getChildAt(this.mCurrentTab + 1);
indicatorLeft = indicatorLeft + mCurrentPositionOffset * (currentTabView.getWidth() / 2 + nextTab.getWidth() / 2);
}

mIndicatorRect.left = (int) indicatorLeft;
mIndicatorRect.right = (int) (mIndicatorRect.left + mIndicatorWidth);
}
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

if (isInEditMode() || mTabCount <= 0) {
return;
}

int height = getHeight();
int paddingLeft = getPaddingLeft();
// draw divider
if (mDividerWidth > 0) {
mDividerPaint.setStrokeWidth(mDividerWidth);
mDividerPaint.setColor(mDividerColor);
for (int i = 0; i < mTabCount - 1; i++) {
View tab = mTabsContainer.getChildAt(i);
canvas.drawLine(paddingLeft + tab.getRight(), mDividerPadding, paddingLeft + tab.getRight(), height - mDividerPadding, mDividerPaint);
}
}

// draw underline
if (mUnderlineHeight > 0) {
mRectPaint.setColor(mUnderlineColor);
if (mUnderlineGravity == Gravity.BOTTOM) {
canvas.drawRect(paddingLeft, height - mUnderlineHeight, mTabsContainer.getWidth() + paddingLeft, height, mRectPaint);
} else {
canvas.drawRect(paddingLeft, 0, mTabsContainer.getWidth() + paddingLeft, mUnderlineHeight, mRectPaint);
}
}

//draw indicator line

calcIndicatorRect();
if (mIndicatorStyle == STYLE_TRIANGLE) {
if (mIndicatorHeight > 0) {
mTrianglePaint.setColor(mIndicatorColor);
mTrianglePath.reset();
mTrianglePath.moveTo(paddingLeft + mIndicatorRect.left, height);
mTrianglePath.lineTo(paddingLeft + mIndicatorRect.left / 2 + mIndicatorRect.right / 2, height - mIndicatorHeight);
mTrianglePath.lineTo(paddingLeft + mIndicatorRect.right, height);
mTrianglePath.close();
canvas.drawPath(mTrianglePath, mTrianglePaint);
}
} else if (mIndicatorStyle == STYLE_BLOCK) {
if (mIndicatorHeight < 0) {
mIndicatorHeight = height - mIndicatorMarginTop - mIndicatorMarginBottom;
} else {

}

if (mIndicatorHeight > 0) {
if (mIndicatorCornerRadius < 0 || mIndicatorCornerRadius > mIndicatorHeight / 2) {
mIndicatorCornerRadius = mIndicatorHeight / 2;
}

mIndicatorDrawable.setColor(mIndicatorColor);
mIndicatorDrawable.setBounds(paddingLeft + (int) mIndicatorMarginLeft + mIndicatorRect.left,
(int) mIndicatorMarginTop, (int) (paddingLeft + mIndicatorRect.right - mIndicatorMarginRight),
(int) (mIndicatorMarginTop + mIndicatorHeight));
mIndicatorDrawable.setCornerRadius(mIndicatorCornerRadius);
mIndicatorDrawable.draw(canvas);
}
} else {
/* mRectPaint.setColor(mIndicatorColor);
calcIndicatorRect();
canvas.drawRect(getPaddingLeft() + mIndicatorRect.left, getHeight() - mIndicatorHeight,
mIndicatorRect.right + getPaddingLeft(), getHeight(), mRectPaint);*/

if (mIndicatorHeight > 0) {
mIndicatorDrawable.setColor(mIndicatorColor);

if (mIndicatorGravity == Gravity.BOTTOM) {
mIndicatorDrawable.setBounds(paddingLeft + (int) mIndicatorMarginLeft + mIndicatorRect.left,
height - (int) mIndicatorHeight - (int) mIndicatorMarginBottom,
paddingLeft + mIndicatorRect.right - (int) mIndicatorMarginRight,
height - (int) mIndicatorMarginBottom);
} else {
mIndicatorDrawable.setBounds(paddingLeft + (int) mIndicatorMarginLeft + mIndicatorRect.left,
(int) mIndicatorMarginTop,
paddingLeft + mIndicatorRect.right - (int) mIndicatorMarginRight,
(int) mIndicatorHeight + (int) mIndicatorMarginTop);
}
mIndicatorDrawable.setCornerRadius(mIndicatorCornerRadius);
mIndicatorDrawable.draw(canvas);
}
}
}

//setter and getter
public void setCurrentTab(int currentTab) {
this.mCurrentTab = currentTab;
mViewPager.setCurrentItem(currentTab);

}

public void setCurrentTab(int currentTab, boolean smoothScroll) {
this.mCurrentTab = currentTab;
mViewPager.setCurrentItem(currentTab, smoothScroll);
}

public void setIndicatorStyle(int indicatorStyle) {
this.mIndicatorStyle = indicatorStyle;
invalidate();
}

public void setTabPadding(float tabPadding) {
this.mTabPadding = dp2px(tabPadding);
updateTabStyles();
}

public void setTabSpaceEqual(boolean tabSpaceEqual) {
this.mTabSpaceEqual = tabSpaceEqual;
updateTabStyles();
}

public void setTabWidth(float tabWidth) {
this.mTabWidth = dp2px(tabWidth);
updateTabStyles();
}

public void setIndicatorColor(int indicatorColor) {
this.mIndicatorColor = indicatorColor;
invalidate();
}

public void setIndicatorHeight(float indicatorHeight) {
this.mIndicatorHeight = dp2px(indicatorHeight);
invalidate();
}

public void setIndicatorWidth(float indicatorWidth) {
this.mIndicatorWidth = dp2px(indicatorWidth);
invalidate();
}

public void setIndicatorCornerRadius(float indicatorCornerRadius) {
this.mIndicatorCornerRadius = dp2px(indicatorCornerRadius);
invalidate();
}

public void setIndicatorGravity(int indicatorGravity) {
this.mIndicatorGravity = indicatorGravity;
invalidate();
}

public void setIndicatorMargin(float indicatorMarginLeft, float indicatorMarginTop,
float indicatorMarginRight, float indicatorMarginBottom) {
this.mIndicatorMarginLeft = dp2px(indicatorMarginLeft);
this.mIndicatorMarginTop = dp2px(indicatorMarginTop);
this.mIndicatorMarginRight = dp2px(indicatorMarginRight);
this.mIndicatorMarginBottom = dp2px(indicatorMarginBottom);
invalidate();
}

public void setIndicatorWidthEqualTitle(boolean indicatorWidthEqualTitle) {
this.mIndicatorWidthEqualTitle = indicatorWidthEqualTitle;
invalidate();
}

public void setUnderlineColor(int underlineColor) {
this.mUnderlineColor = underlineColor;
invalidate();
}

public void setUnderlineHeight(float underlineHeight) {
this.mUnderlineHeight = dp2px(underlineHeight);
invalidate();
}

public void setUnderlineGravity(int underlineGravity) {
this.mUnderlineGravity = underlineGravity;
invalidate();
}

public void setDividerColor(int dividerColor) {
this.mDividerColor = dividerColor;
invalidate();
}

public void setDividerWidth(float dividerWidth) {
this.mDividerWidth = dp2px(dividerWidth);
invalidate();
}

public void setDividerPadding(float dividerPadding) {
this.mDividerPadding = dp2px(dividerPadding);
invalidate();
}

public void setTextsize(float textsize) {
this.mTextsize = sp2px(textsize);
updateTabStyles();
}

public void setTextSelectColor(int textSelectColor) {
this.mTextSelectColor = textSelectColor;
updateTabStyles();
}

public void setTextUnselectColor(int textUnselectColor) {
this.mTextUnselectColor = textUnselectColor;
updateTabStyles();
}

public void setTextBold(int textBold) {
this.mTextBold = textBold;
updateTabStyles();
}

public void setTextAllCaps(boolean textAllCaps) {
this.mTextAllCaps = textAllCaps;
updateTabStyles();
}

public void setSnapOnTabClick(boolean snapOnTabClick) {
mSnapOnTabClick = snapOnTabClick;
}


public int getTabCount() {
return mTabCount;
}

public int getCurrentTab() {
return mCurrentTab;
}

public int getIndicatorStyle() {
return mIndicatorStyle;
}

public float getTabPadding() {
return mTabPadding;
}

public boolean isTabSpaceEqual() {
return mTabSpaceEqual;
}

public float getTabWidth() {
return mTabWidth;
}

public int getIndicatorColor() {
return mIndicatorColor;
}

public float getIndicatorHeight() {
return mIndicatorHeight;
}

public float getIndicatorWidth() {
return mIndicatorWidth;
}

public float getIndicatorCornerRadius() {
return mIndicatorCornerRadius;
}

public float getIndicatorMarginLeft() {
return mIndicatorMarginLeft;
}

public float getIndicatorMarginTop() {
return mIndicatorMarginTop;
}

public float getIndicatorMarginRight() {
return mIndicatorMarginRight;
}

public float getIndicatorMarginBottom() {
return mIndicatorMarginBottom;
}

public int getUnderlineColor() {
return mUnderlineColor;
}

public float getUnderlineHeight() {
return mUnderlineHeight;
}

public int getDividerColor() {
return mDividerColor;
}

public float getDividerWidth() {
return mDividerWidth;
}

public float getDividerPadding() {
return mDividerPadding;
}

public float getTextsize() {
return mTextsize;
}

public int getTextSelectColor() {
return mTextSelectColor;
}

public int getTextUnselectColor() {
return mTextUnselectColor;
}

public int getTextBold() {
return mTextBold;
}

public boolean isTextAllCaps() {
return mTextAllCaps;
}

public TextView getTitleView(int tab) {
View tabView = mTabsContainer.getChildAt(tab);
TextView tv_tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);
return tv_tab_title;
}

//setter and getter

// show MsgTipView
private Paint mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private SparseArray<Boolean> mInitSetMap = new SparseArray<>();

/**
* 显示未读消息
*
* @param position 显示tab位置
* @param num num小于等于0显示红点,num大于0显示数字
*/
public void showMsg(int position, int num) {
if (position >= mTabCount) {
position = mTabCount - 1;
}

View tabView = mTabsContainer.getChildAt(position);
MsgView tipView = (MsgView) tabView.findViewById(R.id.rtv_msg_tip);
if (tipView != null) {
UnreadMsgUtils.show(tipView, num);

if (mInitSetMap.get(position) != null && mInitSetMap.get(position)) {
return;
}

setMsgMargin(position, 4, 2);
mInitSetMap.put(position, true);
}
}

/**
* 显示未读红点
*
* @param position 显示tab位置
*/
public void showDot(int position) {
if (position >= mTabCount) {
position = mTabCount - 1;
}
showMsg(position, 0);
}

/** 隐藏未读消息 */
public void hideMsg(int position) {
if (position >= mTabCount) {
position = mTabCount - 1;
}

View tabView = mTabsContainer.getChildAt(position);
MsgView tipView = (MsgView) tabView.findViewById(R.id.rtv_msg_tip);
if (tipView != null) {
tipView.setVisibility(View.GONE);
}
}

/** 设置未读消息偏移,原点未文字的右上角.当控件高度固定,消息提示位置易控制,显示效果佳 */
public void setMsgMargin(int position, float leftPadding, float bottomPadding) {
if (position >= mTabCount) {
position = mTabCount - 1;
}
View tabView = mTabsContainer.getChildAt(position);
MsgView tipView = (MsgView) tabView.findViewById(R.id.rtv_msg_tip);
if (tipView != null) {
TextView tv_tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);
mTextPaint.setTextSize(mTextsize);
float textWidth = mTextPaint.measureText(tv_tab_title.getText().toString());
float textHeight = mTextPaint.descent() - mTextPaint.ascent();
MarginLayoutParams lp = (MarginLayoutParams) tipView.getLayoutParams();
lp.leftMargin = mTabWidth >= 0 ? (int) (mTabWidth / 2 + textWidth / 2 + dp2px(leftPadding)) : (int) (mTabPadding + textWidth + dp2px(leftPadding));
lp.topMargin = mHeight > 0 ? (int) (mHeight - textHeight) / 2 - dp2px(bottomPadding) : 0;
tipView.setLayoutParams(lp);
}
}

/** 当前类只提供了少许设置未读消息属性的方法,可以通过该方法获取MsgView对象从而各种设置 */
public MsgView getMsgView(int position) {
if (position >= mTabCount) {
position = mTabCount - 1;
}
View tabView = mTabsContainer.getChildAt(position);
MsgView tipView = (MsgView) tabView.findViewById(R.id.rtv_msg_tip);
return tipView;
}

private OnTabSelectListener mListener;

public void setOnTabSelectListener(OnTabSelectListener listener) {
this.mListener = listener;
}

class InnerPagerAdapter extends FragmentPagerAdapter {
private ArrayList<Fragment> fragments = new ArrayList<>();
private String[] titles;

public InnerPagerAdapter(FragmentManager fm, ArrayList<Fragment> fragments, String[] titles) {
super(fm);
this.fragments = fragments;
this.titles = titles;
}

@Override
public int getCount() {
return fragments.size();
}

@Override
public CharSequence getPageTitle(int position) {
return titles[position];
}

@Override
public Fragment getItem(int position) {
return fragments.get(position);
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// 覆写destroyItem并且空实现,这样每个Fragment中的视图就不会被销毁
// super.destroyItem(container, position, object);
}

@Override
public int getItemPosition(Object object) {
return PagerAdapter.POSITION_NONE;
}
}

@Override
protected Parcelable onSaveInstanceState() {
Bundle bundle = new Bundle();
bundle.putParcelable("instanceState", super.onSaveInstanceState());
bundle.putInt("mCurrentTab", mCurrentTab);
return bundle;
}

@Override
protected void onRestoreInstanceState(Parcelable state) {
if (state instanceof Bundle) {
Bundle bundle = (Bundle) state;
mCurrentTab = bundle.getInt("mCurrentTab");
state = bundle.getParcelable("instanceState");
if (mCurrentTab != 0 && mTabsContainer.getChildCount() > 0) {
updateTabSelection(mCurrentTab);
scrollToCurrentTab();
}
}
super.onRestoreInstanceState(state);
}

protected int dp2px(float dp) {
final float scale = mContext.getResources().getDisplayMetrics().density;
return (int) (dp * scale + 0.5f);
}

protected int sp2px(float sp) {
final float scale = this.mContext.getResources().getDisplayMetrics().scaledDensity;
return (int) (sp * scale + 0.5f);
}
}

+ 53
- 0
app/src/main/java/com/huntersun/vkyes/etcopencard/src/widget/tablayout/UnreadMsgUtils.java ファイルの表示

@@ -0,0 +1,53 @@
package com.huntersun.vkyes.etcopencard.src.widget.tablayout;

import android.util.DisplayMetrics;
import android.view.View;
import android.widget.RelativeLayout;

/**
* Date :2023-03-13
* Description:未读消息提示View,显示小红点或者带有数字的红点
*/
public class UnreadMsgUtils {
public static void show(MsgView msgView, int num) {
if (msgView == null) {
return;
}
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) msgView.getLayoutParams();
DisplayMetrics dm = msgView.getResources().getDisplayMetrics();
msgView.setVisibility(View.VISIBLE);
if (num <= 0) {//圆点,设置默认宽高
msgView.setStrokeWidth(0);
msgView.setText("");

lp.width = (int) (5 * dm.density);
lp.height = (int) (5 * dm.density);
msgView.setLayoutParams(lp);
} else {
lp.height = (int) (18 * dm.density);
if (num > 0 && num < 10) {//圆
lp.width = (int) (18 * dm.density);
msgView.setText(num + "");
} else if (num > 9 && num < 100) {//圆角矩形,圆角是高度的一半,设置默认padding
lp.width = RelativeLayout.LayoutParams.WRAP_CONTENT;
msgView.setPadding((int) (6 * dm.density), 0, (int) (6 * dm.density), 0);
msgView.setText(num + "");
} else {//数字超过两位,显示99+
lp.width = RelativeLayout.LayoutParams.WRAP_CONTENT;
msgView.setPadding((int) (6 * dm.density), 0, (int) (6 * dm.density), 0);
msgView.setText("99+");
}
msgView.setLayoutParams(lp);
}
}

public static void setSize(MsgView rtv, int size) {
if (rtv == null) {
return;
}
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) rtv.getLayoutParams();
lp.width = size;
lp.height = size;
rtv.setLayoutParams(lp);
}
}

+ 8
- 0
app/src/main/res/drawable-v1/border_dark_green_radius.xml ファイルの表示

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="@dimen/dp_50"/>
<solid android:color="@color/transparent"/>
<stroke
android:width="@dimen/dp_1"
android:color="@color/common_accent_color" />
</shape>

+ 8
- 0
app/src/main/res/drawable-v1/border_dark_grey_radius.xml ファイルの表示

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="@dimen/dp_50"/>
<solid android:color="@color/transparent"/>
<stroke
android:width="@dimen/dp_1"
android:color="@color/color_666666" />
</shape>

+ 8
- 0
app/src/main/res/drawable-v1/border_grey_white_radius.xml ファイルの表示

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="@dimen/dp_10"/>
<solid android:color="@color/white"/>
<stroke
android:width="@dimen/dp_0_5"
android:color="#CCCCCC" />
</shape>

+ 173
- 0
app/src/main/res/layout-v3/item_recharge_record.xml ファイルの表示

@@ -0,0 +1,173 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout"
style="@style/MatchWrap.Vertical"
android:layout_marginHorizontal="@dimen/dp_15"
android:layout_marginTop="@dimen/dp_10"
android:background="@drawable/border_grey_white_radius"
android:orientation="vertical"
android:paddingHorizontal="@dimen/dp_15"
android:paddingVertical="@dimen/dp_15">

<LinearLayout
style="@style/MatchWrap.Horizontal"
android:gravity="center">

<TextView
android:id="@+id/tvOrderId"
style="@style/AutoWrap"
android:text=""
android:textColor="@color/color_333333"
android:textSize="@dimen/sp_14" />

<TextView
android:id="@+id/tvOrderStatus"
style="@style/WrapWrap"
android:text=""
android:textColor="@color/common_accent_color"
android:textSize="@dimen/sp_14" />
</LinearLayout>

<View
style="@style/MatchOne.HorLine"
android:layout_marginVertical="@dimen/dp_15" />

<LinearLayout style="@style/MatchWrap.Horizontal">

<TextView
style="@style/AutoWrap"
android:text="圈存单号"
android:textColor="@color/color_666666"
android:textSize="@dimen/sp_14" />

<TextView
android:id="@+id/tvQcId"
style="@style/WrapWrap"
android:text=""
android:textColor="@color/color_333333"
android:textSize="@dimen/sp_14" />
</LinearLayout>

<LinearLayout
style="@style/MatchWrap.Horizontal"
android:layout_marginTop="@dimen/dp_12">

<TextView
style="@style/AutoWrap"
android:text="ETC卡号"
android:textColor="@color/color_666666"
android:textSize="@dimen/sp_14" />

<TextView
android:id="@+id/tvEtcNum"
style="@style/WrapWrap"
android:text=""
android:textColor="@color/color_333333"
android:textSize="@dimen/sp_14" />
</LinearLayout>

<LinearLayout
style="@style/MatchWrap.Horizontal"
android:layout_marginTop="@dimen/dp_12">

<TextView
style="@style/AutoWrap"
android:text="业务类型"
android:textColor="@color/color_666666"
android:textSize="@dimen/sp_14" />

<TextView
android:id="@+id/tvType"
style="@style/WrapWrap"
android:text=""
android:textColor="@color/color_333333"
android:textSize="@dimen/sp_14" />
</LinearLayout>

<LinearLayout
style="@style/MatchWrap.Horizontal"
android:layout_marginTop="@dimen/dp_12">

<TextView
style="@style/AutoWrap"
android:text="圈存时间"
android:textColor="@color/color_666666"
android:textSize="@dimen/sp_14" />

<TextView
android:id="@+id/tvTime"
style="@style/WrapWrap"
android:textColor="@color/color_333333"
android:textSize="@dimen/sp_14" />
</LinearLayout>

<LinearLayout
style="@style/MatchWrap.Horizontal"
android:layout_marginTop="@dimen/dp_12">

<TextView
style="@style/AutoWrap"
android:text="圈存金额"
android:textColor="@color/color_666666"
android:textSize="@dimen/sp_14" />

<TextView
android:id="@+id/tvMoney"
style="@style/WrapWrap"
android:textColor="@color/color_FF8000"
android:textSize="@dimen/sp_14" />
</LinearLayout>

<LinearLayout
style="@style/MatchWrap.Horizontal"
android:layout_marginTop="@dimen/dp_12">

<TextView
style="@style/AutoWrap"
android:text="支付方式"
android:textColor="@color/color_666666"
android:textSize="@dimen/sp_14" />

<TextView
android:id="@+id/tvPayType"
style="@style/WrapWrap"
android:textColor="@color/color_333333"
android:textSize="@dimen/sp_14" />
</LinearLayout>

<LinearLayout
android:id="@+id/LLBtns"
style="@style/MatchWrap.Vertical">

<View
style="@style/MatchOne.HorLine"
android:layout_marginVertical="@dimen/dp_15" />

<LinearLayout
style="@style/MatchWrap.Horizontal"
android:gravity="right|center_vertical">

<TextView
android:id="@+id/btnGrey"
style="@style/WrapWrap"
android:background="@drawable/border_dark_grey_radius"
android:paddingHorizontal="@dimen/dp_10"
android:paddingVertical="@dimen/dp_7"
android:text="申请退款"
android:textColor="@color/color_666666"
android:textSize="@dimen/sp_12" />

<TextView
android:id="@+id/btnGreen"
style="@style/WrapWrap"
android:layout_marginLeft="@dimen/dp_15"
android:background="@drawable/border_dark_green_radius"
android:paddingHorizontal="@dimen/dp_10"
android:paddingVertical="@dimen/dp_7"
android:text="圈存修复"
android:textColor="@color/common_accent_color"
android:textSize="@dimen/sp_12" />
</LinearLayout>
</LinearLayout>

</LinearLayout>

+ 3
- 2
app/src/main/res/layout/activity_qc_step1.xml ファイルの表示

@@ -21,7 +21,7 @@
<!--搜索框-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/dp_30"
android:layout_height="@dimen/dp_35"
android:layout_marginHorizontal="@dimen/dp_25"
android:layout_marginTop="@dimen/dp_20"
android:background="@drawable/item_home_frame3"
@@ -43,7 +43,8 @@
android:layout_height="@dimen/dp_30"
android:drawablePadding="@dimen/dp_10"
android:hint="请输入订单编号/车牌号"
android:textColor="#ff999999"
android:textColorHint="@color/color_999999"
android:textColor="@color/color_333333"
android:textSize="@dimen/sp_12"/>
</LinearLayout>


+ 150
- 2
app/src/main/res/layout/activity_recharge_record.xml ファイルの表示

@@ -1,6 +1,154 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
xmlns:app="http://schemas.android.com/apk/res-auto"
style="@style/MatchMatch.Vertical"
android:background="@color/background_color">

<com.hjq.bar.TitleBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
app:leftIcon="@mipmap/back_black"
app:lineVisible="false"
app:title="充值记录"
app:titleColor="@color/black" />

<!--搜索框-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/dp_35"
android:layout_marginHorizontal="@dimen/dp_25"
android:layout_marginTop="@dimen/dp_15"
android:background="@drawable/item_home_frame3"
android:gravity="center_vertical"
android:paddingHorizontal="@dimen/dp_12">

<ImageView
android:layout_width="@dimen/dp_15"
android:layout_height="@dimen/dp_15"
android:src="@drawable/search_ic" />

<com.hjq.widget.view.ClearEditText
android:id="@+id/et_search"
style="@style/EditTextStyle"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_35"
android:drawablePadding="@dimen/dp_10"
android:gravity="center_vertical"
android:hint="请输入订单编号/车牌号"
android:textColor="@color/color_333333"
android:textColorHint="@color/color_999999"
android:textSize="@dimen/sp_12" />
</LinearLayout>

<!--筛选条件 -->
<LinearLayout
style="@style/MatchWrap.Horizontal"
android:layout_marginHorizontal="@dimen/dp_25"
android:layout_marginTop="@dimen/dp_15"
android:layout_marginBottom="@dimen/dp_15">

<LinearLayout
android:id="@+id/ll_time"
style="@style/AutoWrap.Horizontal"
android:layout_height="@dimen/dp_35"
android:background="@drawable/item_home_frame3"
android:gravity="center_vertical"
android:paddingHorizontal="@dimen/dp_12">

<TextView
android:id="@+id/et_date"
android:layout_width="0dp"
android:layout_height="@dimen/dp_30"
android:layout_weight="1"
android:drawablePadding="@dimen/dp_10"
android:gravity="center_vertical"
android:hint="圈存时间"
android:paddingTop="0dp"
android:paddingBottom="0dp"
android:textColor="@color/color_333333"
android:textColorHint="@color/color_999999"
android:textSize="@dimen/sp_12" />

<ImageView
android:layout_width="@dimen/dp_15"
android:layout_height="@dimen/dp_15"
android:src="@mipmap/icon_date" />
</LinearLayout>

<LinearLayout
android:id="@+id/ll_pay_type"
style="@style/AutoWrap.Horizontal"
android:layout_height="@dimen/dp_35"
android:layout_marginLeft="@dimen/dp_10"
android:background="@drawable/item_home_frame3"
android:gravity="center_vertical"
android:paddingHorizontal="@dimen/dp_12">

<TextView
android:id="@+id/et_pay_type"
android:layout_width="0dp"
android:layout_height="@dimen/dp_30"
android:layout_weight="1"
android:drawablePadding="@dimen/dp_10"
android:gravity="center_vertical"
android:hint="支付方式"
android:paddingTop="0dp"
android:paddingBottom="0dp"
android:textColor="@color/color_333333"
android:textColorHint="@color/color_999999"
android:textSize="@dimen/sp_12" />

<ImageView
android:layout_width="@dimen/dp_12"
android:layout_height="@dimen/dp_7"
android:src="@mipmap/icon_down_grey" />
</LinearLayout>

<Button
android:id="@+id/btn_check"
style="@style/BtnShortStyle"
android:layout_width="@dimen/dp_60"
android:layout_height="@dimen/dp_35"
android:layout_gravity="center_vertical|right"
android:layout_marginLeft="@dimen/dp_10"
android:text="查询"
android:textSize="@dimen/sp_12" />
</LinearLayout>

<com.hjq.shape.layout.ShapeLinearLayout
style="@style/MatchWrap.Vertical"
android:background="@color/white"
android:paddingTop="@dimen/dp_10"
app:shape="rectangle"
app:shape_solidColor="@color/white"
app:shape_topLeftRadius="@dimen/dp_20"
app:shape_topRightRadius="@dimen/dp_20">

<com.huntersun.vkyes.etcopencard.src.widget.tablayout.SlidingTabLayout
android:id="@+id/tab_title"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_30"
android:background="@color/white"
app:divider_color="@color/transparent"
app:divider_padding="0dp"
app:divider_width="0dp"
app:indicator_color="@color/common_accent_color"
app:indicator_corner_radius="@dimen/dp_50"
app:indicator_height="3dp"
app:indicator_width="@dimen/dp_20"
app:mv_cornerRadius="50dp"
app:tab_space_equal="true"
app:textSelectColor="@color/common_accent_color"
app:textUnselectColor="@color/color_333333"
app:textsize="@dimen/sp_14"
app:underline_color="@color/transparent"
app:underline_height="0dp" />

<androidx.viewpager.widget.ViewPager
android:id="@+id/viewpager"
style="@style/MatchMatch" />
</com.hjq.shape.layout.ShapeLinearLayout>


</LinearLayout>

+ 68
- 3
app/src/main/res/layout/dialog_recharge_confirm.xml ファイルの表示

@@ -1,6 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<com.hjq.shape.layout.ShapeLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="@color/white"
android:orientation="vertical"
app:shape="rectangle"
app:shape_solidColor="@color/white"
app:shape_topLeftRadius="@dimen/dp_20"
app:shape_topRightRadius="@dimen/dp_20">

</LinearLayout>
<LinearLayout
style="@style/MatchWrap.Vertical"
android:paddingHorizontal="@dimen/dp_15">
<LinearLayout
style="@style/MatchWrap.Horizontal"
android:paddingTop="@dimen/dp_25"
android:paddingBottom="@dimen/dp_20"
android:paddingHorizontal="@dimen/dp_15">

<TextView
style="@style/AutoWrap"
android:text="圈存金额"
android:textColor="@color/color_333333"
android:textSize="@dimen/sp_14"
/>

<TextView
android:id="@+id/pay_money"
style="@style/WrapWrap"
android:text="¥ 0.00"
android:textColor="@color/common_accent_color"
android:textSize="@dimen/sp_14"
android:textStyle="bold"/>
</LinearLayout>
<View style="@style/MatchOne.HorLine"/>

<LinearLayout
style="@style/MatchWrap.Horizontal"
android:paddingTop="@dimen/dp_20"
android:paddingHorizontal="@dimen/dp_15">

<TextView
style="@style/WrapWrap"
android:text="账户余额剩余:"
android:textSize="@dimen/sp_14"
android:textColor="@color/color_333333"/>

<TextView
android:id="@+id/balance"
style="@style/WrapWrap"
android:text="¥ 0.00"
android:textSize="@dimen/sp_14"
android:textColor="#FF8000"/>
</LinearLayout>

<Button
android:id="@+id/btn_recharge"
style="@style/BtnShortStyle"
android:layout_width="@dimen/dp_150"
android:layout_height="@dimen/dp_45"
android:layout_gravity="center"
android:layout_marginTop="@dimen/dp_30"
android:layout_marginBottom="@dimen/dp_40"
android:text="立即充值"
android:textSize="@dimen/sp_15" />
</LinearLayout>
</com.hjq.shape.layout.ShapeLinearLayout>

+ 27
- 0
app/src/main/res/layout/fragment_recharge_record.xml ファイルの表示

@@ -0,0 +1,27 @@
<?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">

<com.huntersun.vkyes.etcopencard.src.widget.StatusLayout
android:id="@+id/hl_status_hint"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.scwang.smart.refresh.layout.SmartRefreshLayout
android:id="@+id/rl_status_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:srlEnablePreviewInEditMode="false">

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler"
style="@style/MatchMatch"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/item_recharge_record" />
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
</com.huntersun.vkyes.etcopencard.src.widget.StatusLayout>

</LinearLayout>

+ 31
- 0
app/src/main/res/layout/layout_tab.xml ファイルの表示

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false">

<TextView
android:id="@+id/tv_tab_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:singleLine="true"/>

<com.huntersun.vkyes.etcopencard.src.widget.tablayout.MsgView
android:id="@+id/rtv_msg_tip"
xmlns:mv="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="#ffffff"
android:textSize="11.5sp"
android:visibility="visible"
mv:mv_backgroundColor="@color/common_accent_color"
mv:mv_isRadiusHalfHeight="true"
mv:mv_strokeColor="#ffffff"
mv:mv_strokeWidth="0dp"/>

</RelativeLayout>

バイナリ
app/src/main/res/mipmap-xhdpi/icon_date.png ファイルの表示


バイナリ
app/src/main/res/mipmap-xhdpi/icon_down_grey.png ファイルの表示


+ 60
- 0
app/src/main/res/values/styles.xml ファイルの表示

@@ -290,4 +290,64 @@
<item name="android:gravity">center_vertical|center_horizontal</item>
<item name="android:enabled">false</item>
</style>
<!--TabLayout-->
<declare-styleable name="SlidingTabLayoutAttr">
<!-- indicator -->
<attr name="indicator_color" format="color" />
<attr name="indicator_height" format="dimension" />
<attr name="indicator_width" format="dimension" />
<attr name="indicator_margin_left" format="dimension" />
<attr name="indicator_margin_top" format="dimension" />
<attr name="indicator_margin_right" format="dimension" />
<attr name="indicator_margin_bottom" format="dimension" />
<attr name="indicator_corner_radius" format="dimension" />
<attr name="indicator_gravity" format="integer" />
<attr name="indicator_style" format="integer" />
<attr name="indicator_width_equal_title" format="boolean" />
<!-- underline -->
<attr name="underline_color" format="color" />
<attr name="underline_height" format="dimension" />
<attr name="underline_gravity" format="integer" />
<!-- divider -->
<attr name="divider_color" format="color" />
<attr name="divider_width" format="dimension" />
<attr name="divider_padding" format="dimension" />
<!-- tab -->
<attr name="tab_padding" format="dimension" />
<attr name="tab_space_equal" format="boolean" />
<attr name="tab_width" format="dimension" />
<!-- title -->
<attr name="textsize" format="dimension" />
<attr name="textSelectColor" format="color" />
<attr name="textUnselectColor" format="color" />
<attr name="textBold" format="integer" />
<attr name="textAllCaps" format="boolean" />
<!-- subtitle -->
<attr name="subTextSize" format="dimension" />
<attr name="subTextSelectColor" format="color" />
<attr name="subTextUnSelectColor" format="color" />
<attr name="subTextBold" format="integer" />
<attr name="subTextAllCaps" format="boolean" />
</declare-styleable>
<declare-styleable name="MsgView">
<!-- 圆角矩形背景色 -->
<attr name="mv_backgroundColor" format="color" />
<!-- 圆角弧度,单位dp-->
<attr name="mv_cornerRadius" format="dimension" />
<!-- 圆角弧度,单位dp-->
<attr name="mv_strokeWidth" format="dimension" />
<!-- 圆角边框颜色-->
<attr name="mv_strokeColor" format="color" />
<!-- 圆角弧度是高度一半-->
<attr name="mv_isRadiusHalfHeight" format="boolean" />
<!-- 圆角矩形宽高相等,取较宽高中大值-->
<attr name="mv_isWidthHeightEqual" format="boolean" />
</declare-styleable>
</resources>

+ 2
- 0
library/base/src/main/res/values/colors.xml ファイルの表示

@@ -71,6 +71,8 @@

<!-- 文字颜色-->
<color name="color_333333">#333333</color>
<color name="color_666666">#666666</color>
<color name="color_999999">#999999</color>
<color name="color_F7F6FB">#F7F6FB</color>
<color name="color_FF8000">#FF8000</color>
</resources>

読み込み中…
キャンセル
保存