diff --git a/app/build.gradle b/app/build.gradle index 7f38f5ff..49dc8dd4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -17,7 +17,7 @@ android { } defaultConfig { applicationId "com.qxcm.qxlive" - minSdk 24 + minSdk 26 targetSdk 33 versionCode Integer.parseInt(project.findProperty("APP_VERSION_CODE")) versionName project.findProperty("APP_VERSION_NAME") @@ -66,19 +66,19 @@ android { // // 测试版配置 beta { -// dimension "environment" -// // 测试版包名:基础包名 + .beta(com.example.myapp.beta) -// applicationIdSuffix ".beta" -// // 测试版版本名:1.0-beta -// versionNameSuffix "-beta" -// -// // 【测试版应用名称】动态生成带标识的名称 -// resValue "string", "app_name", "羽声-测试版" -// -// // 【测试版图标】替换为测试专用图标 -// manifestPlaceholders = [ -// appIcon: "@mipmap/ic_launcher_app_bat" // 需在main/res/mipmap放置该图标 -// ] + dimension "environment" + // 测试版包名:基础包名 + .beta(com.example.myapp.beta) + applicationIdSuffix ".beta" + // 测试版版本名:1.0-beta + versionNameSuffix "-beta" + + // 【测试版应用名称】动态生成带标识的名称 + resValue "string", "app_name", "羽声-测试版" + + // 【测试版图标】替换为测试专用图标 + manifestPlaceholders = [ + appIcon: "@mipmap/ic_launcher_app_bat" // 需在main/res/mipmap放置该图标 + ] } } diff --git a/app/src/main/java/com/qxcm/qxlive/wxapi/WXPayEntryActivity.java b/app/src/main/java/com/qxcm/qxlive/wxapi/WXPayEntryActivity.java index 84f07eb6..f4381aac 100644 --- a/app/src/main/java/com/qxcm/qxlive/wxapi/WXPayEntryActivity.java +++ b/app/src/main/java/com/qxcm/qxlive/wxapi/WXPayEntryActivity.java @@ -46,7 +46,8 @@ public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler { switch (resp.errCode) { case BaseResp.ErrCode.ERR_OK: // 支付成功:这里需要调用后台接口确认支付状态(避免本地判断不可靠) - + PayEvent messageEvent = new PayEvent(1, "支付成功"); + EventBus.getDefault().post(messageEvent); break; case BaseResp.ErrCode.ERR_USER_CANCEL: checkPayResultFromServer(); diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 18c32476..f90eaa4f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -57,6 +57,10 @@ xbanner = "1.7.0" legacySupportV4 = "1.0.0" fragmentKtx = "1.5.6" interpolator = "1.0.0" +material3Android = "1.4.0" +uiToolingPreviewAndroid = "1.9.4" +tilesToolingPreview = "1.5.0" +constraintlayoutVersion = "2.2.1" [libraries] alipay-alipaysdk-android = { module = "com.alipay.sdk:alipaysdk-android", version.ref = "alipayAlipaysdkAndroid" } @@ -118,6 +122,10 @@ zcw-togglebutton-library = { module = "com.zcw:togglebutton-library", version.re androidx-legacy-support-v4 = { group = "androidx.legacy", name = "legacy-support-v4", version.ref = "legacySupportV4" } androidx-fragment-ktx = { group = "androidx.fragment", name = "fragment-ktx", version.ref = "fragmentKtx" } androidx-interpolator = { group = "androidx.interpolator", name = "interpolator", version.ref = "interpolator" } +androidx-material3-android = { group = "androidx.compose.material3", name = "material3-android", version.ref = "material3Android" } +androidx-ui-tooling-preview-android = { group = "androidx.compose.ui", name = "ui-tooling-preview-android", version.ref = "uiToolingPreviewAndroid" } +androidx-tiles-tooling-preview = { group = "androidx.wear.tiles", name = "tiles-tooling-preview", version.ref = "tilesToolingPreview" } +androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayoutVersion" } [plugins] diff --git a/locktableview/.gitignore b/locktableview/.gitignore new file mode 100644 index 00000000..796b96d1 --- /dev/null +++ b/locktableview/.gitignore @@ -0,0 +1 @@ +/build diff --git a/locktableview/build.gradle b/locktableview/build.gradle new file mode 100644 index 00000000..f194f3bb --- /dev/null +++ b/locktableview/build.gradle @@ -0,0 +1,31 @@ +apply plugin: 'com.android.library' +group='com.github.RmondJone' +android { + namespace 'com.rmondjone.locktableview' + compileSdk 35 + + defaultConfig { + minSdk 24 + targetSdk 35 + versionCode 12 + versionName "1.1.2" + + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + // 1. 核心:AppCompat 依赖(必须添加,主题基础) + implementation 'androidx.appcompat:appcompat:1.6.1' + implementation 'com.android.support:design:25.0.0' + + implementation project(':moduleUtil') +} diff --git a/locktableview/src/main/AndroidManifest.xml b/locktableview/src/main/AndroidManifest.xml new file mode 100644 index 00000000..7ce9595d --- /dev/null +++ b/locktableview/src/main/AndroidManifest.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/locktableview/src/main/java/com/rmondjone/locktableview/CustomHorizontalScrollView.java b/locktableview/src/main/java/com/rmondjone/locktableview/CustomHorizontalScrollView.java new file mode 100644 index 00000000..6b27ab5e --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/locktableview/CustomHorizontalScrollView.java @@ -0,0 +1,106 @@ +package com.rmondjone.locktableview; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.widget.HorizontalScrollView; + +/** + * 说明 自定义水平滚动视图,解决ScrollView在API23以下没有滚动监听事件问题 + * 作者 郭翰林 + * 创建时间 2017/3/31. + */ + +public class CustomHorizontalScrollView extends HorizontalScrollView { + //触摸前的点 + private float x; + + //手势抬起之后的点 + private float x1; + + private onScrollChangeListener onScrollChangeListener; + + public CustomHorizontalScrollView(Context context) { + super(context); + } + + public CustomHorizontalScrollView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public CustomHorizontalScrollView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + public interface onScrollChangeListener { + /** + * 滚动监听 + * + * @param scrollView + * @param x + * @param y + */ + void onScrollChanged(HorizontalScrollView scrollView, int x, int y); + + /** + * 滑动到最左侧 + * + * @param scrollView + */ + void onScrollFarLeft(HorizontalScrollView scrollView); + + /** + * 滑动到最右侧 + * + * @param scrollView + */ + void onScrollFarRight(HorizontalScrollView scrollView); + } + + @Override + public boolean onTouchEvent(MotionEvent ev) { + switch (ev.getAction()) { + case MotionEvent.ACTION_DOWN: + x = ev.getX(); + break; + case MotionEvent.ACTION_UP: + x1 = ev.getX(); + if (computeHorizontalScrollOffset() == 0 && x-x1<0) { + //滑动最左边 + if (onScrollChangeListener != null) { + onScrollChangeListener.onScrollFarLeft(this); + } + } else if (computeHorizontalScrollRange() - computeHorizontalScrollOffset() + <= computeHorizontalScrollExtent() && x-x1>0) { + //滑动最右边 + if (onScrollChangeListener != null) { + onScrollChangeListener.onScrollFarRight(this); + } + } + break; + default: + break; + } + return super.onTouchEvent(ev); + } + + /** + * 设置监听 + * + * @param onScrollChangeListener + */ + public void setOnScrollChangeListener(CustomHorizontalScrollView.onScrollChangeListener onScrollChangeListener) { + this.onScrollChangeListener = onScrollChangeListener; + } + + + @Override + protected void onScrollChanged(int l, int t, int oldl, int oldt) { + super.onScrollChanged(l, t, oldl, oldt); + //回调 + if (onScrollChangeListener != null) { + onScrollChangeListener.onScrollChanged(this, l, t); + } + } + +} diff --git a/locktableview/src/main/java/com/rmondjone/locktableview/DisplayUtil.java b/locktableview/src/main/java/com/rmondjone/locktableview/DisplayUtil.java new file mode 100644 index 00000000..854981b6 --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/locktableview/DisplayUtil.java @@ -0,0 +1,36 @@ +package com.rmondjone.locktableview; + +import android.content.Context; + +/** + * Created by aaron on 16/8/3. + */ +public class DisplayUtil +{ + + public static int screenWidthPx; //屏幕宽 px + public static int screenhightPx; //屏幕高 px + public static float density;//屏幕密度 + public static int densityDPI;//屏幕密度 + public static float screenWidthDip;// dp单位 + public static float screenHightDip;// dp单位 + + + + /** + * 根据手机的分辨率从 dp 的单位 转成为 px(像素) + */ + public static int dip2px(Context context, float dpValue) { + final float scale = context.getResources().getDisplayMetrics().density; + return (int) (dpValue * scale + 0.5f); + } + + /** + * 根据手机的分辨率从 px(像素) 的单位 转成为 dp + */ + public static int px2dip(Context context, float pxValue) { + final float scale = context.getResources().getDisplayMetrics().density; + return (int) (pxValue / scale + 0.5f); + } + +} diff --git a/locktableview/src/main/java/com/rmondjone/locktableview/LockColumnAdapter.java b/locktableview/src/main/java/com/rmondjone/locktableview/LockColumnAdapter.java new file mode 100644 index 00000000..51cd2ee6 --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/locktableview/LockColumnAdapter.java @@ -0,0 +1,281 @@ +package com.rmondjone.locktableview; + +import android.content.Context; +import android.graphics.Color; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.LinearLayout; +import android.widget.NumberPicker; +import android.widget.TextView; + +import androidx.core.content.ContextCompat; +import androidx.recyclerview.widget.RecyclerView; + +import java.util.ArrayList; + +/** + * 说明 + * 作者 郭翰林 + * 创建时间 2017/9/17. + */ + +public class LockColumnAdapter extends RecyclerView.Adapter { + /** + * 上下文 + */ + private Context mContext; + /** + * 第一列数据 + */ + private ArrayList mLockColumnDatas; + /** + * 第一行背景颜色 + */ + private int mFristRowBackGroudColor; + /** + * 表格头部字体颜色 + */ + private int mTableHeadTextColor; + /** + * 表格内容字体颜色 + */ + private int mTableContentTextColor; + /** + * 是否锁定首行 + */ + private boolean isLockFristRow = true; + /** + * 记录每列最大宽度 + */ + private ArrayList mColumnMaxWidths = new ArrayList(); + /** + * 记录每行最大高度 + */ + private ArrayList mRowMaxHeights = new ArrayList(); + + /** + * 单元格字体大小 + */ + private int mTextViewSize; + /** + * 单元格内边距 + */ + private int mCellPadding; + + /** + * Item点击事件 + */ + private LockTableView.OnItemClickListenter mOnItemClickListenter; + + /** + * Item长按事件 + */ + private LockTableView.OnItemLongClickListenter mOnItemLongClickListenter; + + /** + * Item项被选中监听(处理被选中的效果) + */ + private TableViewAdapter.OnItemSelectedListenter mOnItemSelectedListenter; + /** + * 是否启用交替行背景 + */ + private boolean isAlternateRowBackground = false; + /** + * 交替行背景颜色1(透明) + */ + private int mAlternateRowColor1 = Color.TRANSPARENT; + /** + * 交替行背景颜色2(#323252) + */ + private int mAlternateRowColor2 = Color.parseColor("#323252"); + +// ... 在构造方法后添加以下方法 + + public void setAlternateRowBackground(boolean alternateRowBackground) { + isAlternateRowBackground = alternateRowBackground; + } + + public void setAlternateRowColors(int color1, int color2) { + mAlternateRowColor1 = color1; + mAlternateRowColor2 = color2; + } + + public LockColumnAdapter(Context mContext, ArrayList mLockColumnDatas) { + this.mContext = mContext; + this.mLockColumnDatas = mLockColumnDatas; + } + + + @Override + public LockViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + LockViewHolder holder = new LockViewHolder(LayoutInflater.from(mContext).inflate(R.layout.lock_item, null)); + return holder; + } + + @Override + public void onBindViewHolder(LockViewHolder holder, final int position) { + // 设置交替行背景颜色 + if (isAlternateRowBackground && !isLockFristRow) { + if (position % 2 == 0) { + holder.mLinearLayout.setBackgroundColor(mAlternateRowColor1); // 偶数行透明 + } else { + holder.mLinearLayout.setBackgroundColor(mAlternateRowColor2); // 奇数行#323252 + } + } else if (isAlternateRowBackground && isLockFristRow) { + // 如果锁定首行,从第二行开始计算交替背景 + if (position % 2 == 1) { + holder.mLinearLayout.setBackgroundColor(mAlternateRowColor1); // 偶数行透明 + } else { + holder.mLinearLayout.setBackgroundColor(mAlternateRowColor2); // 奇数行#323252 + } + } + + //设置布局 + holder.mTextView.setText(mLockColumnDatas.get(position)); + holder.mTextView.setTextSize(mTextViewSize); + LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) holder.mTextView.getLayoutParams(); + layoutParams.width = DisplayUtil.dip2px(mContext, mColumnMaxWidths.get(0)); + if (isLockFristRow) { + layoutParams.height = DisplayUtil.dip2px(mContext, mRowMaxHeights.get(position + 1)); + } else { + layoutParams.height = DisplayUtil.dip2px(mContext, mRowMaxHeights.get(position)); + } + layoutParams.setMargins(mCellPadding, mCellPadding, mCellPadding, mCellPadding); + holder.mTextView.setLayoutParams(layoutParams); + //设置颜色 + if (!isLockFristRow) { + if (position == 0) { + holder.mLinearLayout.setBackgroundColor(ContextCompat.getColor(mContext, mFristRowBackGroudColor)); + holder.mTextView.setTextColor(ContextCompat.getColor(mContext, mTableHeadTextColor)); + } else { + holder.mTextView.setTextColor(ContextCompat.getColor(mContext, mTableContentTextColor)); + } + } else { + holder.mTextView.setTextColor(ContextCompat.getColor(mContext, mTableContentTextColor)); + } + //添加事件 + if(mOnItemClickListenter!=null){ + holder.mLinearLayout.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if(mOnItemSelectedListenter!=null){ + mOnItemSelectedListenter.onItemSelected(v,position); + } + if(isLockFristRow){ + mOnItemClickListenter.onItemClick(v,position+1); + }else{ + if(position!=0){ + mOnItemClickListenter.onItemClick(v,position); + } + } + } + }); + } + if(mOnItemLongClickListenter!=null){ + holder.mLinearLayout.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + if(mOnItemSelectedListenter!=null){ + mOnItemSelectedListenter.onItemSelected(v,position); + } + if (isLockFristRow){ + mOnItemLongClickListenter.onItemLongClick(v,position+1); + }else{ + if(position!=0){ + mOnItemLongClickListenter.onItemLongClick(v,position); + } + } + return true; + } + }); + } + //如果没有设置点击事件和长按事件 + if(mOnItemClickListenter==null&&mOnItemLongClickListenter==null){ + holder.mLinearLayout.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if(mOnItemSelectedListenter!=null){ + mOnItemSelectedListenter.onItemSelected(v,position); + } + } + }); + holder.mLinearLayout.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + if(mOnItemSelectedListenter!=null){ + mOnItemSelectedListenter.onItemSelected(v,position); + } + return true; + } + }); + } + } + + @Override + public int getItemCount() { + return mLockColumnDatas.size(); + } + + @Override + public int getItemViewType(int position) { + return position; + } + + class LockViewHolder extends RecyclerView.ViewHolder { + TextView mTextView; + LinearLayout mLinearLayout; + + public LockViewHolder(View itemView) { + super(itemView); + mTextView = (TextView) itemView.findViewById(R.id.lock_text); + mLinearLayout = (LinearLayout) itemView.findViewById(R.id.lock_linearlayout); + } + } + + + //取得每行每列应用高宽 + public void setColumnMaxWidths(ArrayList mColumnMaxWidths) { + this.mColumnMaxWidths = mColumnMaxWidths; + } + + public void setRowMaxHeights(ArrayList mRowMaxHeights) { + this.mRowMaxHeights = mRowMaxHeights; + } + + public void setTextViewSize(int mTextViewSize) { + this.mTextViewSize = mTextViewSize; + } + + public void setLockFristRow(boolean lockFristRow) { + isLockFristRow = lockFristRow; + } + + public void setCellPadding(int mCellPadding) { + this.mCellPadding = mCellPadding; + } + + public void setFristRowBackGroudColor(int mFristRowBackGroudColor) { + this.mFristRowBackGroudColor = mFristRowBackGroudColor; + } + + public void setTableHeadTextColor(int mTableHeadTextColor) { + this.mTableHeadTextColor = mTableHeadTextColor; + } + + public void setTableContentTextColor(int mTableContentTextColor) { + this.mTableContentTextColor = mTableContentTextColor; + } + + public void setOnItemClickListenter(LockTableView.OnItemClickListenter mOnItemClickListenter) { + this.mOnItemClickListenter = mOnItemClickListenter; + } + + public void setOnItemLongClickListenter(LockTableView.OnItemLongClickListenter mOnItemLongClickListenter) { + this.mOnItemLongClickListenter = mOnItemLongClickListenter; + } + + public void setOnItemSelectedListenter(TableViewAdapter.OnItemSelectedListenter mOnItemSelectedListenter) { + this.mOnItemSelectedListenter = mOnItemSelectedListenter; + } +} diff --git a/locktableview/src/main/java/com/rmondjone/locktableview/LockTableView.java b/locktableview/src/main/java/com/rmondjone/locktableview/LockTableView.java new file mode 100644 index 00000000..8d39539f --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/locktableview/LockTableView.java @@ -0,0 +1,993 @@ +package com.rmondjone.locktableview; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.text.Layout; +import android.text.StaticLayout; +import android.text.TextPaint; +import android.text.method.NumberKeyListener; +import android.util.Log; +import android.util.TypedValue; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.HorizontalScrollView; +import android.widget.LinearLayout; +import android.widget.ScrollView; +import android.widget.TextView; +import android.widget.Toast; + + +import androidx.core.content.ContextCompat; +import androidx.recyclerview.widget.LinearLayoutManager; + +import com.rmondjone.xrecyclerview.ProgressStyle; +import com.rmondjone.xrecyclerview.XRecyclerView; +import com.xscm.moduleutil.bean.TableCellData; + +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + * 说明 可锁定首行和首列的表格视图 + * 作者 郭翰林 + * 创建时间 2017/3/29. + */ + +public class LockTableView { + /** + * 上下文 + */ + private Context mContext; + /** + * 表格父视图 + */ + private ViewGroup mContentView; + /** + * 表格数据,每一行为一条数据,从表头计算 + */ + private ArrayList> mTableDatas = new ArrayList>(); + /** + * 表格视图 + */ + private View mTableView; + /** + * 是否锁定首行 + */ + private boolean isLockFristRow = true; + /** + * 是否锁定首列 + */ + private boolean isLockFristColumn = true; + /** + * 最大列宽(dp) + */ + private int maxColumnWidth; + /** + * 最小列宽(dp) + */ + private int minColumnWidth; + /** + * 最大行高(dp) + */ + private int maxRowHeight; + /** + * 最小行高dp) + */ + private int minRowHeight; + /** + * 第一行背景颜色 + */ + private int mFristRowBackGroudColor; + /** + * 数据为空时的缺省值 + */ + private TableCellData mNullableString; + /** + * 单元格字体大小 + */ + private int mTextViewSize; + /** + * 表格头部字体颜色 + */ + private int mTableHeadTextColor; + /** + * 表格内容字体颜色 + */ + private int mTableContentTextColor; + /** + * 表格横向滚动监听事件 + */ + private OnTableViewListener mTableViewListener; + + /** + * 表格横向滚动到边界监听事件 + */ + private OnTableViewRangeListener mTableViewRangeListener; + + /** + * 表格上拉刷新、下拉加载监听事件 + */ + private OnLoadingListener mOnLoadingListener; + /** + * Item点击事件 + */ + private OnItemClickListenter mOnItemClickListenter; + /** + * Item长按事件 + */ + private OnItemLongClickListenter mOnItemLongClickListenter; + /** + * Item选中样式 + */ + private int mOnItemSeletor; + /** + * 单元格内边距 + */ + private int mCellPadding; + /** + * 要改变的列集合 + */ + private HashMap mChangeColumns = new HashMap<>(); + + + //表格数据 + /** + * 表格第一行数据,不包括第一个元素 + */ + private ArrayList mTableFristData = new ArrayList<>(); + /** + * 表格第一列数据,不包括第一个元素 + */ + private ArrayList mTableColumnDatas = new ArrayList<>(); + /** + * 表格左上角数据 + */ + private String mColumnTitle; + /** + * 表格每一行数据,不包括第一行和第一列 + */ + private ArrayList> mTableRowDatas = new ArrayList>(); + /** + * 记录每列最大宽度 + */ + private ArrayList mColumnMaxWidths = new ArrayList(); + /** + * 记录每行最大高度 + */ + private ArrayList mRowMaxHeights = new ArrayList(); + /** + * 把所有的滚动视图放图列表,后面实现联动效果 + */ + private ArrayList mScrollViews = new ArrayList(); + + + //表格视图 + /** + * 表格左上角视图 + */ + private TextView mColumnTitleView; + /** + * 第一行布局(锁状态) + */ + private LinearLayout mLockHeadView; + /** + * 第一行布局(未锁状态) + */ + private LinearLayout mUnLockHeadView; + /** + * 第一行滚动视图(锁状态) + */ + private CustomHorizontalScrollView mLockScrollView; + /** + * 第一行滚动视图(未锁状态) + */ + private CustomHorizontalScrollView mUnLockScrollView; + /** + * 表格主视图 + */ + private XRecyclerView mTableScrollView; + /** + * 列表适配器 + */ + private TableViewAdapter mTableViewAdapter; + + + /** + * 构造方法 + * + * @param mContext 上下文 + * @param mContentView 表格父视图 + * @param mTableDatas 表格数据 + */ + public LockTableView(Context mContext, ViewGroup mContentView, ArrayList> mTableDatas) { + this.mContext = mContext; + this.mContentView = mContentView; + this.mTableDatas = mTableDatas; + initAttrs(); + } + + /** + * 初始化属性 + */ + private void initAttrs() { + mTableView = LayoutInflater.from(mContext).inflate(R.layout.locktableview, null); + maxColumnWidth =60; + minColumnWidth = 30; + minRowHeight = 42; + maxRowHeight = 42; + mTableHeadTextColor = R.color.beijin; + mTableContentTextColor = R.color.border_color; + mFristRowBackGroudColor = R.color.table_head; + mTextViewSize = 14; + mCellPadding=DisplayUtil.dip2px(mContext,11); + } + + /** + * 展现视图 + */ + public void show() { + initData(); + initView(); + mContentView.removeAllViews();//清空视图 + mContentView.addView(mTableView); + } + + + /** + * 初始化表格数据 + */ + private void initData() { + if (mTableDatas != null && mTableDatas.size() > 0) { + //检查数据,如果有一行数据长度不一致,以最长为标准填"N/A"字符串,如果有null也替换 + int maxLength = 0; + for (int i = 0; i < mTableDatas.size(); i++) { + if (mTableDatas.get(i).size() >= maxLength) { + maxLength = mTableDatas.get(i).size(); + } + ArrayList rowDatas = mTableDatas.get(i); + for (int j = 0; j < rowDatas.size(); j++) { + if (rowDatas.get(j) == null || rowDatas.get(j).equals("")) { + rowDatas.set(j, mNullableString); + } + } + mTableDatas.set(i, rowDatas); + } +// Log.e("每行最多个数",maxLength+""); + for (int i = 0; i < mTableDatas.size(); i++) { + ArrayList rowDatas = mTableDatas.get(i); + if (rowDatas.size() < maxLength) { + int size = maxLength - rowDatas.size(); + for (int j = 0; j < size; j++) { + rowDatas.add(mNullableString); + } + mTableDatas.set(i, rowDatas); + } + } + +// //测试 +// for (int i=0;i rowDatas=mTableDatas.get(i); +// StringBuffer b=new StringBuffer(); +// for (String str:rowDatas){ +// b.append("["+str+"]"); +// } +// Log.e("第"+i+"行数据",b.toString()+"/"+rowDatas.size()+"个"); +// } + //初始化每列最大宽度 + for (int i = 0; i < mTableDatas.size(); i++) { + ArrayList rowDatas = mTableDatas.get(i); + StringBuffer buffer = new StringBuffer(); + for (int j = 0; j < rowDatas.size(); j++) { + TextView textView = new TextView(mContext); + textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTextViewSize); + textView.setText(rowDatas.get(j).getTitle()); + textView.setGravity(Gravity.CENTER); + //设置布局 + LinearLayout.LayoutParams textViewParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, + LinearLayout.LayoutParams.WRAP_CONTENT); + textViewParams.setMargins(mCellPadding, mCellPadding, mCellPadding, mCellPadding);//android:layout_margin="15dp" + textView.setLayoutParams(textViewParams); + if (i == 0) { + mColumnMaxWidths.add(measureTextWidth(textView, rowDatas.get(j).getTitle())); + buffer.append("[" + measureTextWidth(textView, rowDatas.get(j).getTitle()) + "]"); + } else { + int length = mColumnMaxWidths.get(j); + int current = measureTextWidth(textView, rowDatas.get(j).getTitle()); + if (current > length) { + mColumnMaxWidths.set(j, current); + } + buffer.append("[" + measureTextWidth(textView, rowDatas.get(j).getTitle()) + "]"); + } + } +// Log.e("第"+i+"行列最大宽度",buffer.toString()); + } + //如果用户指定某列宽度则按照用户指定宽度算 + if (mChangeColumns.size() > 0) { + for (Integer key : mChangeColumns.keySet()) { + changeColumnWidth(key, mChangeColumns.get(key)); + } + } +// Log.e("每列最大宽度dp:",mColumnMaxWidths.toString()); + + + //初始化每行最大高度 + for (int i = 0; i < mTableDatas.size(); i++) { + ArrayList rowDatas = mTableDatas.get(i); + StringBuffer buffer = new StringBuffer(); + + TextView textView = new TextView(mContext); + textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTextViewSize); + textView.setGravity(Gravity.CENTER); + //设置布局 + LinearLayout.LayoutParams textViewParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, + LinearLayout.LayoutParams.WRAP_CONTENT); + textViewParams.setMargins(mCellPadding, mCellPadding, mCellPadding, mCellPadding);//android:layout_margin="15dp" + textView.setLayoutParams(textViewParams); + int maxHeight = measureTextHeight(textView, rowDatas.get(0).getTitle()); + mRowMaxHeights.add(maxHeight); + for (int j = 0; j < rowDatas.size(); j++) { + int currentHeight; + //如果用户指定某列宽度则按照用户指定宽度算对应列的高度 + if (mChangeColumns.size() > 0 && mChangeColumns.containsKey(j)) { + currentHeight = getTextViewHeight(textView, rowDatas.get(j).getTitle(), mChangeColumns.get(j)); + } else { + currentHeight = measureTextHeight(textView, rowDatas.get(j).getTitle()); + } + buffer.append("[" + currentHeight + "]"); + if (currentHeight > maxHeight) { + mRowMaxHeights.set(i, currentHeight); + } + } +// Log.e("第"+i+"行高度",buffer.toString()); + } +// Log.e("每行最大高度dp:",mRowMaxHeights.toString()); + + if (isLockFristRow) { + ArrayList fristRowDatas = (ArrayList) mTableDatas.get(0).clone(); + if (isLockFristColumn) { + //锁定第一列 + mColumnTitle = fristRowDatas.get(0).getTitle(); + fristRowDatas.remove(0); + mTableFristData.addAll(fristRowDatas); + //构造第一列数据,并且构造表格每行数据 + for (int i = 1; i < mTableDatas.size(); i++) { + ArrayList rowDatas = (ArrayList) mTableDatas.get(i).clone(); + mTableColumnDatas.add(rowDatas.get(0).getTitle()); + rowDatas.remove(0); + mTableRowDatas.add(rowDatas); + } + } else { + mTableFristData.addAll(fristRowDatas); + for (int i = 1; i < mTableDatas.size(); i++) { + mTableRowDatas.add(mTableDatas.get(i)); + } + } + } else { + if (isLockFristColumn) { + //锁定第一列 + //构造第一列数据,并且构造表格每行数据 + for (int i = 0; i < mTableDatas.size(); i++) { + ArrayList rowDatas = (ArrayList) mTableDatas.get(i).clone(); + mTableColumnDatas.add(rowDatas.get(0).getTitle()); + rowDatas.remove(0); + mTableRowDatas.add(rowDatas); + } + } else { + for (int i = 0; i < mTableDatas.size(); i++) { + mTableRowDatas.add(mTableDatas.get(i)); + } + } + } +// Log.e("第一行数据", mTableFristData.toString()); +// Log.e("第一列数据", mTableColumnDatas.toString()); +// Log.e("每行数据", mTableRowDatas.toString()); + } else { + Toast.makeText(mContext, "表格数据为空!", Toast.LENGTH_SHORT).show(); + } + } + + /** + * 初始化表格视图 + */ + private void initView() { + mColumnTitleView = (TextView) mTableView.findViewById(R.id.lockHeadView_Text); + mLockHeadView = (LinearLayout) mTableView.findViewById(R.id.lockHeadView); + mUnLockHeadView = (LinearLayout) mTableView.findViewById(R.id.unLockHeadView); + mLockScrollView = (CustomHorizontalScrollView) mTableView.findViewById(R.id.lockHeadView_ScrollView); + mUnLockScrollView = (CustomHorizontalScrollView) mTableView.findViewById(R.id.unlockHeadView_ScrollView); + //表格主视图 + mTableScrollView = (XRecyclerView) mTableView.findViewById(R.id.table_scrollView); + LinearLayoutManager layoutManager = new LinearLayoutManager(mContext); + layoutManager.setOrientation(LinearLayoutManager.VERTICAL); + mTableScrollView.setLayoutManager(layoutManager); +// mTableScrollView.setArrowImageView(R.drawable.iconfont_downgrey); +// mTableScrollView.setRefreshProgressStyle(ProgressStyle.BallRotate); +// mTableScrollView.setLoadingMoreProgressStyle(ProgressStyle.BallRotate); +// mTableScrollView.setLoadingListener(new XRecyclerView.LoadingListener() { +// @Override +// public void onRefresh() { +// if (mOnLoadingListener != null) { +// mOnLoadingListener.onRefresh(mTableScrollView, mTableDatas); +// } +// } +// +// @Override +// public void onLoadMore() { +// if (mOnLoadingListener != null) { +// mOnLoadingListener.onLoadMore(mTableScrollView, mTableDatas); +// } +// } +// }); + mTableViewAdapter = new TableViewAdapter(mContext, mTableColumnDatas, mTableRowDatas, isLockFristColumn, isLockFristRow); + mTableViewAdapter.setCellPadding(mCellPadding); + mTableViewAdapter.setColumnMaxWidths(mColumnMaxWidths); + mTableViewAdapter.setRowMaxHeights(mRowMaxHeights); + mTableViewAdapter.setTextViewSize(mTextViewSize); + mTableViewAdapter.setTableContentTextColor(mTableContentTextColor); + mTableViewAdapter.setTableHeadTextColor(mTableHeadTextColor); + mTableViewAdapter.setFristRowBackGroudColor(mFristRowBackGroudColor); + mTableViewAdapter.setHorizontalScrollView(new OnTableViewListener() { + @Override + public void onTableViewScrollChange(int x, int y) { + changeAllScrollView(x, y); + } + }); +// if (mOnItemClickListenter != null) { + mTableViewAdapter.setOnItemClickListenter(null); +// } +// if (mOnItemLongClickListenter != null) { +// mTableViewAdapter.setOnItemLongClickListenter(mOnItemLongClickListenter); +// } +// if (mOnItemSeletor != 0) { +// mTableViewAdapter.setOnItemSeletor(mOnItemSeletor); +// } else { +// mTableViewAdapter.setOnItemSeletor(R.color.dashline_color); +// } + mTableViewAdapter.setTableViewRangeListener(new OnTableViewRangeListener() { + @Override + public void onLeft(HorizontalScrollView view) { + if (mTableViewRangeListener != null) { + mTableViewRangeListener.onLeft(view); + } + } + + @Override + public void onRight(HorizontalScrollView view) { + if (mTableViewRangeListener != null) { + mTableViewRangeListener.onRight(view); + } + } + }); + mTableViewAdapter.setOnTableViewCreatedListener(new TableViewAdapter.OnTableViewCreatedListener() { + @Override + public void onTableViewCreatedCompleted(CustomHorizontalScrollView mScrollView) { + mScrollViews.add(mScrollView); + } + }); + mTableScrollView.setAdapter(mTableViewAdapter); + + mLockHeadView.setBackgroundColor(ContextCompat.getColor(mContext, mFristRowBackGroudColor)); + mUnLockHeadView.setBackgroundColor(ContextCompat.getColor(mContext, mFristRowBackGroudColor)); + if (isLockFristRow) { + if (isLockFristColumn) { + mLockHeadView.setVisibility(View.VISIBLE); + mUnLockHeadView.setVisibility(View.GONE); + } else { + mLockHeadView.setVisibility(View.GONE); + mUnLockHeadView.setVisibility(View.VISIBLE); + } + creatHeadView(); + } else { + mLockHeadView.setVisibility(View.GONE); + mUnLockHeadView.setVisibility(View.GONE); + } + } + + /** + * 创建头部视图 + */ + private void creatHeadView() { + if (isLockFristColumn) { + mColumnTitleView.setTextColor(ContextCompat.getColor(mContext, mTableHeadTextColor)); + mColumnTitleView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTextViewSize); + mColumnTitleView.setText(mColumnTitle); + LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) mColumnTitleView.getLayoutParams(); + layoutParams.width = DisplayUtil.dip2px(mContext, mColumnMaxWidths.get(0)); + layoutParams.height = DisplayUtil.dip2px(mContext, mRowMaxHeights.get(0)); + layoutParams.setMargins(mCellPadding, mCellPadding, mCellPadding, mCellPadding); + mColumnTitleView.setLayoutParams(layoutParams); + //构造滚动视图 + createScollview(mLockScrollView, mTableFristData, true); + mScrollViews.add(mLockScrollView); + mLockScrollView.setOnScrollChangeListener(new CustomHorizontalScrollView.onScrollChangeListener() { + @Override + public void onScrollChanged(HorizontalScrollView scrollView, int x, int y) { + changeAllScrollView(x, y); + } + + @Override + public void onScrollFarLeft(HorizontalScrollView scrollView) { + if (mTableViewRangeListener != null) { + mTableViewRangeListener.onLeft(scrollView); + } + } + + @Override + public void onScrollFarRight(HorizontalScrollView scrollView) { + if (mTableViewRangeListener != null) { + mTableViewRangeListener.onRight(scrollView); + } + } + }); + } else { + createScollview(mUnLockScrollView, mTableFristData, true); + mScrollViews.add(mUnLockScrollView); + mUnLockScrollView.setOnScrollChangeListener(new CustomHorizontalScrollView.onScrollChangeListener() { + @Override + public void onScrollChanged(HorizontalScrollView scrollView, int x, int y) { + changeAllScrollView(x, y); + } + + @Override + public void onScrollFarLeft(HorizontalScrollView scrollView) { + if (mTableViewRangeListener != null) { + mTableViewRangeListener.onLeft(scrollView); + } + } + + @Override + public void onScrollFarRight(HorizontalScrollView scrollView) { + if (mTableViewRangeListener != null) { + mTableViewRangeListener.onRight(scrollView); + } + } + }); + } + } + + + /** + * 改变所有滚动视图位置 + * + * @param x + * @param y + */ + private void changeAllScrollView(int x, int y) { + if (mScrollViews.size() > 0) { + if (mTableViewListener != null) { + mTableViewListener.onTableViewScrollChange(x, y); + } + for (int i = 0; i < mScrollViews.size(); i++) { + HorizontalScrollView scrollView = mScrollViews.get(i); + scrollView.scrollTo(x, y); + } + } + } + + /** + * 根据最大最小值,计算TextView的宽度 + * + * @param textView + * @param text + * @return + */ + private int measureTextWidth(TextView textView, String text) { + if (textView != null) { + LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) textView.getLayoutParams(); + int width = DisplayUtil.px2dip(mContext, layoutParams.leftMargin) + + DisplayUtil.px2dip(mContext, layoutParams.rightMargin) + + getTextViewWidth(textView, text); + if (width <= minColumnWidth) { + return minColumnWidth; + } else if (width > minColumnWidth && width <= maxColumnWidth) { + return width; + } else { + return maxColumnWidth; + } + } + return 0; + } + + /** + * 计算TextView高度 + * + * @param textView + * @param text + * @return + */ + private int measureTextHeight(TextView textView, String text) { + if (textView != null) { + LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) textView.getLayoutParams(); + int height = getTextViewHeight(textView, text); + if (height < minRowHeight) { + return minRowHeight; + } else if (height > minRowHeight && height < maxRowHeight) { + return height; + } else { + return maxRowHeight; + } + } + return 0; + } + + /** + * 根据文字计算textview的高度 + * + * @param textView + * @param text + * @return + */ + private int getTextViewHeight(TextView textView, String text) { + if (textView != null) { + int width = measureTextWidth(textView, text); + TextPaint textPaint = textView.getPaint(); + StaticLayout staticLayout = new StaticLayout(text, textPaint, DisplayUtil.dip2px(mContext, width), Layout.Alignment.ALIGN_NORMAL, 1, 0, false); + int height = DisplayUtil.px2dip(mContext, staticLayout.getHeight()); + return height; + } + return 0; + } + + /** + * 说明 根据文字和指定宽度计算高度 + * 作者 郭翰林 + * 创建时间 2018/3/15 下午12:39 + * + * @param textView + * @param text + * @param width + * @return + */ + private int getTextViewHeight(TextView textView, String text, int width) { + if (textView != null) { + TextPaint textPaint = textView.getPaint(); + StaticLayout staticLayout = new StaticLayout(text, textPaint, DisplayUtil.dip2px(mContext, width), Layout.Alignment.ALIGN_NORMAL, 1, 0, false); + int height = DisplayUtil.px2dip(mContext, staticLayout.getHeight()); + return height; + } + return 0; + } + + /** + * 根据文字计算textview的高度 + * + * @param view + * @param text + * @return + */ + private int getTextViewWidth(TextView view, String text) { + if (view != null) { + TextPaint paint = view.getPaint(); + return DisplayUtil.px2dip(mContext, (int) paint.measureText(text)); + } + return 0; + } + + + /** + * 构造滚动视图 + * + * @param scrollView + * @param datas + * @param isFristRow 是否是第一行 + */ + private void createScollview(HorizontalScrollView scrollView, List datas, boolean isFristRow) { + //设置LinearLayout + LinearLayout linearLayout = new LinearLayout(mContext); + LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, + LinearLayout.LayoutParams.MATCH_PARENT); + linearLayout.setLayoutParams(layoutParams); + linearLayout.setGravity(Gravity.CENTER); + linearLayout.setOrientation(LinearLayout.HORIZONTAL); + for (int i = 0; i < datas.size(); i++) { + //构造单元格 + TextView textView = new TextView(mContext); + if (isFristRow) { + textView.setTextColor(ContextCompat.getColor(mContext, mTableHeadTextColor)); + } else { + textView.setTextColor(ContextCompat.getColor(mContext, mTableContentTextColor)); + } + textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTextViewSize); + textView.setGravity(Gravity.CENTER); + textView.setText(datas.get(i).getTitle()); + //设置布局 + LinearLayout.LayoutParams textViewParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, + LinearLayout.LayoutParams.WRAP_CONTENT); + textViewParams.setMargins(mCellPadding, mCellPadding, mCellPadding, mCellPadding); + textView.setLayoutParams(textViewParams); + ViewGroup.LayoutParams textViewParamsCopy = textView.getLayoutParams(); + if (isLockFristColumn) { + textViewParamsCopy.width = DisplayUtil.dip2px(mContext, mColumnMaxWidths.get(i + 1)); + } else { + textViewParamsCopy.width = DisplayUtil.dip2px(mContext, mColumnMaxWidths.get(i)); + } + linearLayout.addView(textView); +// //画分隔线 +// if (i != datas.size() - 1) { +// View splitView = new View(mContext); +// ViewGroup.LayoutParams splitViewParmas = new ViewGroup.LayoutParams(DisplayUtil.dip2px(mContext, 1), +// ViewGroup.LayoutParams.MATCH_PARENT); +// splitView.setLayoutParams(splitViewParmas); +// if (isFristRow) { +// splitView.setBackgroundColor(ContextCompat.getColor(mContext, R.color.white)); +// } else { +// splitView.setBackgroundColor(ContextCompat.getColor(mContext, R.color.light_gray)); +// } +// linearLayout.addView(splitView); +// } + } + scrollView.addView(linearLayout); + } + + /** + * 说明 改变指定列指定宽度 + * 作者 郭翰林 + * 创建时间 2018/3/15 上午11:06 + * + * @param mColumnNum + * @param mColumnWidth + */ + private void changeColumnWidth(int mColumnNum, int mColumnWidth) { + if (mColumnMaxWidths != null && mColumnMaxWidths.size() > 0) { + if (mColumnNum < mColumnMaxWidths.size() && mColumnNum >= 0) { + mColumnMaxWidths.set(mColumnNum, mColumnWidth + DisplayUtil.px2dip(mContext, 15) * 2); + } else { + Log.e("LockTableView", "指定列数不存在"); + } + } + } + + + //属性设置 + public LockTableView setLockFristRow(boolean lockFristRow) { + isLockFristRow = lockFristRow; + return this; + } + + public LockTableView setLockFristColumn(boolean lockFristColumn) { + isLockFristColumn = lockFristColumn; + return this; + } + + public LockTableView setMaxColumnWidth(int maxColumnWidth) { + this.maxColumnWidth = maxColumnWidth; + return this; + } + + public LockTableView setMinColumnWidth(int minColumnWidth) { + this.minColumnWidth = minColumnWidth; + return this; + } + + public LockTableView setFristRowBackGroudColor(int mFristRowBackGroudColor) { + this.mFristRowBackGroudColor = mFristRowBackGroudColor; + return this; + } + + public LockTableView setNullableString(TableCellData mNullableString) { + this.mNullableString = mNullableString; + return this; + } + + public LockTableView setTextViewSize(int mTextViewSize) { + this.mTextViewSize = mTextViewSize; + return this; + } + + public LockTableView setTableHeadTextColor(int mTableHeadTextColor) { + this.mTableHeadTextColor = mTableHeadTextColor; + return this; + } + + public LockTableView setTableContentTextColor(int mTableContentTextColor) { + this.mTableContentTextColor = mTableContentTextColor; + return this; + } + + public LockTableView setMaxRowHeight(int maxRowHeight) { + this.maxRowHeight = maxRowHeight; + return this; + } + + public LockTableView setMinRowHeight(int minRowHeight) { + this.minRowHeight = minRowHeight; + return this; + } + + public LockTableView setTableViewListener(OnTableViewListener mTableViewListener) { + this.mTableViewListener = mTableViewListener; + return this; + } + + public LockTableView setOnLoadingListener(OnLoadingListener mOnLoadingListener) { + this.mOnLoadingListener = mOnLoadingListener; + return this; + } + + public LockTableView setTableViewRangeListener(OnTableViewRangeListener mTableViewRangeListener) { + this.mTableViewRangeListener = mTableViewRangeListener; + return this; + } + + public LockTableView setOnItemClickListenter(OnItemClickListenter mOnItemClickListenter) { + this.mOnItemClickListenter = mOnItemClickListenter; + return this; + } + + public LockTableView setOnItemLongClickListenter(OnItemLongClickListenter mOnItemLongClickListenter) { + this.mOnItemLongClickListenter = mOnItemLongClickListenter; + return this; + } + + public LockTableView setOnItemSeletor(int mOnItemSeletor) { + this.mOnItemSeletor = mOnItemSeletor; + return this; + } + + public LockTableView setCellPadding(int mCellPadding) { + this.mCellPadding = DisplayUtil.dip2px(mContext,mCellPadding); + return this; + } + + /** + * 指定第几列对应的宽度 + * + * @param mColumnNum + * @param mColumnWidth + * @return + */ + public LockTableView setColumnWidth(int mColumnNum, int mColumnWidth) { + //判断是否已经设置过 + if (mChangeColumns.containsKey(mColumnNum)) { + mChangeColumns.remove(mColumnNum); + } + mChangeColumns.put(mColumnNum, mColumnWidth); + return this; + } + + //值获取 + public ArrayList getColumnMaxWidths() { + return mColumnMaxWidths; + } + + public ArrayList getRowMaxHeights() { + return mRowMaxHeights; + } + + public LinearLayout getLockHeadView() { + return mLockHeadView; + } + + public LinearLayout getUnLockHeadView() { + return mUnLockHeadView; + } + + public XRecyclerView getTableScrollView() { + return mTableScrollView; + } + + public ArrayList getScrollViews() { + return mScrollViews; + } + + /** + * 说明 数据刷新时,重新设值 + * 作者 郭翰林 + * 创建时间 2017/9/17 下午2:33 + * + * @param mTableDatas + */ + public void setTableDatas(ArrayList> mTableDatas) { + this.mTableDatas = mTableDatas; + mTableFristData.clear(); + mTableColumnDatas.clear(); + mTableRowDatas.clear(); + mColumnMaxWidths.clear(); + mRowMaxHeights.clear(); + initData(); + mTableViewAdapter.notifyDataSetChanged(); + } + + + /** + * 横向滚动监听 + */ + public interface OnTableViewListener { + /** + * 滚动监听 + * + * @param x + * @param y + */ + void onTableViewScrollChange(int x, int y); + } + + + /** + * 横向滚动视图滑动到边界的监听 + */ + public interface OnTableViewRangeListener { + + /** + * 说明 最左侧 + * 作者 郭翰林 + * 创建时间 2017/12/14 下午4:45 + * + * @param view + */ + void onLeft(HorizontalScrollView view); + + /** + * 说明 最右侧 + * 作者 郭翰林 + * 创建时间 2017/12/14 下午4:45 + * + * @param view + */ + void onRight(HorizontalScrollView view); + + } + + /** + * 上拉刷新,下拉加载 + */ + public interface OnLoadingListener { + + /** + * 说明 下拉刷新 + * 作者 郭翰林 + * 创建时间 2017/9/17 下午1:54 + * + * @param mXRecyclerView + * @param mTableDatas + */ + void onRefresh(XRecyclerView mXRecyclerView, ArrayList> mTableDatas); + + /** + * 说明 上拉加载 + * 作者 郭翰林 + * 创建时间 2017/9/17 下午1:55 + * + * @param mXRecyclerView + * @param mTableDatas + */ + void onLoadMore(XRecyclerView mXRecyclerView, ArrayList> mTableDatas); + } + + + /** + * 说明 Item点击事件 + * 作者 郭翰林 + * 创建时间 2018/2/2 下午4:50 + */ + public interface OnItemClickListenter { + + /** + * @param item 点击项 + * @param position 点击位置 + */ + void onItemClick(View item, int position); + } + + /** + * 说明 Item长按事件 + * 作者 郭翰林 + * 创建时间 2018/2/2 下午4:50 + */ + public interface OnItemLongClickListenter { + + /** + * @param item 点击项 + * @param position 点击位置 + */ + void onItemLongClick(View item, int position); + } +} diff --git a/locktableview/src/main/java/com/rmondjone/locktableview/TableViewAdapter.java b/locktableview/src/main/java/com/rmondjone/locktableview/TableViewAdapter.java new file mode 100644 index 00000000..c1ed8a89 --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/locktableview/TableViewAdapter.java @@ -0,0 +1,376 @@ +package com.rmondjone.locktableview; + +import android.content.Context; +import android.graphics.Color; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.HorizontalScrollView; + +import androidx.core.content.ContextCompat; +import androidx.recyclerview.widget.DividerItemDecoration; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.rmondjone.xrecyclerview.XRecyclerView; +import com.xscm.moduleutil.bean.TableCellData; + +import java.util.ArrayList; + +/** + * 说明 + * 作者 郭翰林 + * 创建时间 2017/9/17. + */ + +public class TableViewAdapter extends RecyclerView.Adapter { + /** + * 上下文 + */ + private Context mContext; + /** + * 第一列数据 + */ + private ArrayList mLockColumnDatas; + /** + * 表格数据 + */ + private ArrayList> mTableDatas; + + /** + * 第一列是否被锁定 + */ + private boolean isLockColumn; + /** + * 第一行是否被锁定 + */ + private boolean isLockFristRow; + /** + * 记录每列最大宽度 + */ + private ArrayList mColumnMaxWidths = new ArrayList(); + /** + * 记录每行最大高度 + */ + private ArrayList mRowMaxHeights = new ArrayList(); + + /** + * 单元格字体大小 + */ + private int mTextViewSize; + /** + * 第一行背景颜色 + */ + private int mFristRowBackGroudColor; + /** + * 表格头部字体颜色 + */ + private int mTableHeadTextColor; + /** + * 表格内容字体颜色 + */ + private int mTableContentTextColor; + + /** + * 单元格内边距 + */ + private int mCellPadding; + + /** + * 表格横向滚动监听事件 + */ + private LockTableView.OnTableViewListener mTableViewListener; + + /** + * 表格横向滚动到边界监听事件 + */ + private LockTableView.OnTableViewRangeListener mTableViewRangeListener; + + /** + * Item点击事件 + */ + private LockTableView.OnItemClickListenter mOnItemClickListenter; + + /** + * Item长按事件 + */ + private LockTableView.OnItemLongClickListenter mOnItemLongClickListenter; + + /** + * Item选中样式 + */ + private int mOnItemSeletor; + + /** + * 表格视图加载完成监听事件 + */ + private OnTableViewCreatedListener mOnTableViewCreatedListener; + + + /** + * 锁定视图Adapter + */ + private LockColumnAdapter mLockAdapter; + + /** + * 未锁定视图Adapter + */ + private UnLockColumnAdapter mUnLockAdapter; + + + /** + * 构造方法 + * + * @param mContext + * @param mLockColumnDatas + * @param mTableDatas + * @param isLockColumn + */ + public TableViewAdapter(Context mContext, ArrayList mLockColumnDatas, ArrayList> mTableDatas, boolean isLockColumn, boolean isLockRow) { + this.mContext = mContext; + this.mLockColumnDatas = mLockColumnDatas; + this.mTableDatas = mTableDatas; + this.isLockColumn = isLockColumn; + this.isLockFristRow = isLockRow; + } + + + @Override + public TableViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + TableViewHolder mTableViewHolder = new TableViewHolder(LayoutInflater.from(mContext).inflate(R.layout.locktablecontentview, null)); + if (mOnTableViewCreatedListener != null) { + mOnTableViewCreatedListener.onTableViewCreatedCompleted(mTableViewHolder.mScrollView); + } + return mTableViewHolder; + } + + @Override + public void onBindViewHolder(final TableViewHolder holder, int position) { + LinearLayoutManager layoutManager = new LinearLayoutManager(mContext); + layoutManager.setOrientation(LinearLayoutManager.VERTICAL); + if (isLockColumn) { + //构造锁定视图 + holder.mLockRecyclerView.setVisibility(View.VISIBLE); + if (mLockAdapter == null) { + mLockAdapter = new LockColumnAdapter(mContext, mLockColumnDatas); + mLockAdapter.setCellPadding(mCellPadding); + mLockAdapter.setRowMaxHeights(mRowMaxHeights); + mLockAdapter.setColumnMaxWidths(mColumnMaxWidths); + mLockAdapter.setTextViewSize(mTextViewSize); + mLockAdapter.setLockFristRow(isLockFristRow); + mLockAdapter.setFristRowBackGroudColor(mFristRowBackGroudColor); + mLockAdapter.setTableHeadTextColor(mTableHeadTextColor); + mLockAdapter.setTableContentTextColor(mTableContentTextColor); + // 添加交替行背景颜色设置 + mLockAdapter.setAlternateRowBackground(true); +// mLockAdapter.setOnItemSelectedListenter(new OnItemSelectedListenter() { +// @Override +// public void onItemSelected(View view, int position) { +// RecyclerView.LayoutManager mLockLayoutManager = holder.mLockRecyclerView.getLayoutManager(); +// int itemCount=mLockLayoutManager.getItemCount(); +// View item=mLockLayoutManager.getChildAt(position); +// item.setBackgroundColor(ContextCompat.getColor(mContext,mOnItemSeletor)); +// for(int i=0;i mColumnMaxWidths) { + this.mColumnMaxWidths = mColumnMaxWidths; + } + + public void setRowMaxHeights(ArrayList mRowMaxHeights) { + this.mRowMaxHeights = mRowMaxHeights; + } + + public void setTextViewSize(int mTextViewSize) { + this.mTextViewSize = mTextViewSize; + } + + public void setFristRowBackGroudColor(int mFristRowBackGroudColor) { + this.mFristRowBackGroudColor = mFristRowBackGroudColor; + } + + public void setTableHeadTextColor(int mTableHeadTextColor) { + this.mTableHeadTextColor = mTableHeadTextColor; + } + + public void setTableContentTextColor(int mTableContentTextColor) { + this.mTableContentTextColor = mTableContentTextColor; + } + + public void setHorizontalScrollView(LockTableView.OnTableViewListener mTableViewListener) { + this.mTableViewListener = mTableViewListener; + } + + public void setOnTableViewCreatedListener(OnTableViewCreatedListener mOnTableViewCreatedListener) { + this.mOnTableViewCreatedListener = mOnTableViewCreatedListener; + } + + public void setTableViewRangeListener(LockTableView.OnTableViewRangeListener mTableViewRangeListener) { + this.mTableViewRangeListener = mTableViewRangeListener; + } + + public void setOnItemClickListenter(LockTableView.OnItemClickListenter mOnItemClickListenter) { + this.mOnItemClickListenter = mOnItemClickListenter; + } + + public void setOnItemLongClickListenter(LockTableView.OnItemLongClickListenter mOnItemLongClickListenter) { + this.mOnItemLongClickListenter = mOnItemLongClickListenter; + } + + public void setOnItemSeletor(int mOnItemSeletor) { + this.mOnItemSeletor = mOnItemSeletor; + } + + public void setCellPadding(int mCellPadding) { + this.mCellPadding = mCellPadding; + } +} diff --git a/locktableview/src/main/java/com/rmondjone/locktableview/UnLockColumnAdapter.java b/locktableview/src/main/java/com/rmondjone/locktableview/UnLockColumnAdapter.java new file mode 100644 index 00000000..dc83cc46 --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/locktableview/UnLockColumnAdapter.java @@ -0,0 +1,376 @@ +package com.rmondjone.locktableview; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.graphics.Color; +import android.util.TypedValue; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.HorizontalScrollView; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; +import androidx.recyclerview.widget.RecyclerView; +import com.xscm.moduleutil.bean.TableCellData; + +import java.util.ArrayList; +import java.util.List; + +/** + * 说明 + * 作者 郭翰林 + * 创建时间 2017/9/17. + */ + +public class UnLockColumnAdapter extends RecyclerView.Adapter { + /** + * 上下文 + */ + private Context mContext; + /** + * 表格数据 + */ + private ArrayList> mTableDatas; + /** + * 第一行背景颜色 + */ + private int mFristRowBackGroudColor; + /** + * 表格头部字体颜色 + */ + private int mTableHeadTextColor; + /** + * 表格内容字体颜色 + */ + private int mTableContentTextColor; + /** + * 记录每列最大宽度 + */ + private ArrayList mColumnMaxWidths = new ArrayList(); + /** + * 记录每行最大高度 + */ + private ArrayList mRowMaxHeights = new ArrayList(); + /** + * 单元格字体大小 + */ + private int mTextViewSize; + /** + * 是否锁定首行 + */ + private boolean isLockFristRow = true; + /** + * 是否锁定首列 + */ + private boolean isLockFristColumn = true; + + /** + * 单元格内边距 + */ + private int mCellPadding; + + /** + * Item点击事件 + */ + private LockTableView.OnItemClickListenter mOnItemClickListenter; + + /** + * Item长按事件 + */ + private LockTableView.OnItemLongClickListenter mOnItemLongClickListenter; + + /** + * Item项被选中监听(处理被选中的效果) + */ + private TableViewAdapter.OnItemSelectedListenter mOnItemSelectedListenter; + + /** + * 构造方法 + * + * @param mContext + * @param mTableDatas + */ + public UnLockColumnAdapter(Context mContext, ArrayList> mTableDatas) { + this.mContext = mContext; + this.mTableDatas = mTableDatas; + } + + /** + * 是否启用交替行背景 + */ + private boolean isAlternateRowBackground = false; + /** + * 交替行背景颜色1(透明) + */ + private int mAlternateRowColor1 = Color.TRANSPARENT; + /** + * 交替行背景颜色2(#323252) + */ + private int mAlternateRowColor2 = Color.parseColor("#323252"); + +// ... 在构造方法后添加以下方法 + + public void setAlternateRowBackground(boolean alternateRowBackground) { + isAlternateRowBackground = alternateRowBackground; + } + + public void setAlternateRowColors(int color1, int color2) { + mAlternateRowColor1 = color1; + mAlternateRowColor2 = color2; + } + @Override + public int getItemCount() { + return mTableDatas.size(); + } + + @Override + public UnLockViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + UnLockViewHolder holder = new UnLockViewHolder(LayoutInflater.from(mContext).inflate(R.layout.unlock_item, null)); + return holder; + } + + @Override + public void onBindViewHolder(@NonNull UnLockViewHolder holder, @SuppressLint("RecyclerView") int position) { + ArrayList datas = mTableDatas.get(position); + + + // 设置交替行背景颜色 + if (isAlternateRowBackground && !isLockFristRow) { + if (position % 2 == 0) { + holder.mLinearLayout.setBackgroundColor(mAlternateRowColor1); // 偶数行透明 + } else { + holder.mLinearLayout.setBackgroundColor(mAlternateRowColor2); // 奇数行#323252 + } + } else if (isAlternateRowBackground && isLockFristRow) { + // 如果锁定首行,从第二行开始计算交替背景 + if (position % 2 == 1) { + holder.mLinearLayout.setBackgroundColor(mAlternateRowColor1); // 偶数行透明 + } else { + holder.mLinearLayout.setBackgroundColor(mAlternateRowColor2); // 奇数行#323252 + } + } + + if (isLockFristRow) { + //第一行是锁定的 + createRowView(holder.mLinearLayout, datas, false, mRowMaxHeights.get(position + 1)); + } else { + if (position == 0) { + holder.mLinearLayout.setBackgroundColor(ContextCompat.getColor(mContext, mFristRowBackGroudColor)); + createRowView(holder.mLinearLayout, datas, true, mRowMaxHeights.get(position)); + } else { + createRowView(holder.mLinearLayout, datas, false, mRowMaxHeights.get(position)); + } + } + //添加事件 +// if(mOnItemClickListenter!=null){ +// holder.mLinearLayout.setOnClickListener(new View.OnClickListener() { +// @Override +// public void onClick(View v) { +// if(mOnItemSelectedListenter!=null){ +// mOnItemSelectedListenter.onItemSelected(v,position); +// } +// if(isLockFristRow){ +// mOnItemClickListenter.onItemClick(v,position+1); +// }else{ +// if(position!=0){ +// mOnItemClickListenter.onItemClick(v,position); +// } +// } +// } +// }); +// } +// if(mOnItemLongClickListenter!=null){ +// holder.mLinearLayout.setOnLongClickListener(new View.OnLongClickListener() { +// @Override +// public boolean onLongClick(View v) { +// if(mOnItemSelectedListenter!=null){ +// mOnItemSelectedListenter.onItemSelected(v,position); +// } +// if (isLockFristRow){ +// mOnItemLongClickListenter.onItemLongClick(v,position+1); +// }else{ +// if(position!=0){ +// mOnItemLongClickListenter.onItemLongClick(v,position); +// } +// } +// return true; +// } +// }); +// } + //如果没有设置点击事件和长按事件 +// if(mOnItemClickListenter==null&&mOnItemLongClickListenter==null){ +// holder.mLinearLayout.setOnClickListener(new View.OnClickListener() { +// @Override +// public void onClick(View v) { +// if(mOnItemSelectedListenter!=null){ +// mOnItemSelectedListenter.onItemSelected(v,position); +// } +// } +// }); +// holder.mLinearLayout.setOnLongClickListener(new View.OnLongClickListener() { +// @Override +// public boolean onLongClick(View v) { +// if(mOnItemSelectedListenter!=null){ +// mOnItemSelectedListenter.onItemSelected(v,position); +// } +// return true; +// } +// }); +// } + } + + + @Override + public int getItemViewType(int position) { + return position; + } + + + //取得每行每列应用高宽 + public void setColumnMaxWidths(ArrayList mColumnMaxWidths) { + this.mColumnMaxWidths = mColumnMaxWidths; + } + + public void setRowMaxHeights(ArrayList mRowMaxHeights) { + this.mRowMaxHeights = mRowMaxHeights; + } + + public void setTextViewSize(int mTextViewSize) { + this.mTextViewSize = mTextViewSize; + } + + public void setLockFristRow(boolean lockFristRow) { + isLockFristRow = lockFristRow; + } + + public void setFristRowBackGroudColor(int mFristRowBackGroudColor) { + this.mFristRowBackGroudColor = mFristRowBackGroudColor; + } + + public void setTableHeadTextColor(int mTableHeadTextColor) { + this.mTableHeadTextColor = mTableHeadTextColor; + } + + public void setTableContentTextColor(int mTableContentTextColor) { + this.mTableContentTextColor = mTableContentTextColor; + } + + public void setLockFristColumn(boolean lockFristColumn) { + isLockFristColumn = lockFristColumn; + } + + public void setOnItemClickListenter(LockTableView.OnItemClickListenter mOnItemClickListenter) { + this.mOnItemClickListenter = mOnItemClickListenter; + } + + public void setOnItemLongClickListenter(LockTableView.OnItemLongClickListenter mOnItemLongClickListenter) { + this.mOnItemLongClickListenter = mOnItemLongClickListenter; + } + + public void setOnItemSelectedListenter(TableViewAdapter.OnItemSelectedListenter mOnItemSelectedListenter) { + this.mOnItemSelectedListenter = mOnItemSelectedListenter; + } + + public void setCellPadding(int mCellPadding) { + this.mCellPadding = mCellPadding; + } + + class UnLockViewHolder extends RecyclerView.ViewHolder { + LinearLayout mLinearLayout; + + public UnLockViewHolder(View itemView) { + super(itemView); + mLinearLayout = (LinearLayout) itemView.findViewById(R.id.unlock_linearlayout); + } + } + + /** + * 构造每行数据视图 + * + * @param linearLayout + * @param datas + * @param isFristRow 是否是第一行 + */ + private void createRowView(LinearLayout linearLayout, List datas, boolean isFristRow, int mMaxHeight) { + //设置LinearLayout + linearLayout.removeAllViews();//首先清空LinearLayout,复用会造成重复绘制,使内容超出预期长度 + for (int i = 0; i < datas.size(); i++) { + //根据数据内容决定显示ImageView还是TextView + if (datas.get(i).getTitle().equals("1") || datas.get(i).getTitle().equals("0")) { + //显示ImageView + ImageView imageView = new ImageView(mContext); + if (datas.get(i).getTitle().equals("1")) { + imageView.setImageResource(com.xscm.moduleutil.R.mipmap.icon_yes); + } else { + imageView.setImageResource(com.xscm.moduleutil.R.mipmap.icon_no); + } + + //设置布局 + LinearLayout.LayoutParams imageParams = new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.WRAP_CONTENT, + LinearLayout.LayoutParams.WRAP_CONTENT); + imageParams.setMargins(mCellPadding, mCellPadding, mCellPadding, mCellPadding); + imageParams.height = DisplayUtil.dip2px(mContext, mMaxHeight); + if (isLockFristColumn) { + imageParams.width = DisplayUtil.dip2px(mContext, mColumnMaxWidths.get(i+1)); + } else { + imageParams.width = DisplayUtil.dip2px(mContext, mColumnMaxWidths.get(i)); + } + imageView.setLayoutParams(imageParams); + imageView.setScaleType(ImageView.ScaleType.CENTER); + linearLayout.addView(imageView); + } else { + //显示TextView + TextView textView = new TextView(mContext); + if (isFristRow) { + textView.setTextColor(ContextCompat.getColor(mContext, mTableHeadTextColor)); + } else { + textView.setTextColor(ContextCompat.getColor(mContext, mTableContentTextColor)); + } + textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTextViewSize); + textView.setGravity(Gravity.CENTER); + textView.setText(datas.get(i).getTitle()); + // 添加颜色值空值检查 + String color = datas.get(i).getColor(); + if (color != null && !color.isEmpty() && + !color.equals("无")) { + textView.setTextColor(Color.parseColor(color)); + } + + //设置布局 + LinearLayout.LayoutParams textViewParams = new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.WRAP_CONTENT, + LinearLayout.LayoutParams.WRAP_CONTENT); + textViewParams.setMargins(mCellPadding, mCellPadding, mCellPadding, mCellPadding); + textViewParams.height = DisplayUtil.dip2px(mContext, mMaxHeight); + if (isLockFristColumn) { + textViewParams.width = DisplayUtil.dip2px(mContext, mColumnMaxWidths.get(i+1)); + } else { + textViewParams.width = DisplayUtil.dip2px(mContext, mColumnMaxWidths.get(i)); + } + textView.setLayoutParams(textViewParams); + linearLayout.addView(textView); + } + +// //画分隔线 +// if (i != datas.size() - 1) { +// View splitView = new View(mContext); +// ViewGroup.LayoutParams splitViewParmas = new ViewGroup.LayoutParams(DisplayUtil.dip2px(mContext, 1), +// ViewGroup.LayoutParams.MATCH_PARENT); +// splitView.setLayoutParams(splitViewParmas); +// if (isFristRow) { +// splitView.setBackgroundColor(ContextCompat.getColor(mContext, R.color.white)); +// } else { +// splitView.setBackgroundColor(ContextCompat.getColor(mContext, R.color.light_gray)); +// } +// linearLayout.addView(splitView); +// } + } + } + +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/AppBarStateChangeListener.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/AppBarStateChangeListener.java new file mode 100644 index 00000000..78d76d70 --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/AppBarStateChangeListener.java @@ -0,0 +1,41 @@ +package com.rmondjone.xrecyclerview; + + +import com.google.android.material.appbar.AppBarLayout; + +/** + * Created by jianghejie on 16/6/19. + */ + +public abstract class AppBarStateChangeListener implements AppBarLayout.OnOffsetChangedListener { + + public enum State { + EXPANDED, + COLLAPSED, + IDLE + } + + private State mCurrentState = State.IDLE; + + @Override + public final void onOffsetChanged(AppBarLayout appBarLayout, int i) { + if (i == 0) { + if (mCurrentState != State.EXPANDED) { + onStateChanged(appBarLayout, State.EXPANDED); + } + mCurrentState = State.EXPANDED; + } else if (Math.abs(i) >= appBarLayout.getTotalScrollRange()) { + if (mCurrentState != State.COLLAPSED) { + onStateChanged(appBarLayout, State.COLLAPSED); + } + mCurrentState = State.COLLAPSED; + } else { + if (mCurrentState != State.IDLE) { + onStateChanged(appBarLayout, State.IDLE); + } + mCurrentState = State.IDLE; + } + } + public abstract void onStateChanged(AppBarLayout appBarLayout, State state); +} + diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/ArrowRefreshHeader.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/ArrowRefreshHeader.java new file mode 100644 index 00000000..a2eb7a48 --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/ArrowRefreshHeader.java @@ -0,0 +1,268 @@ +package com.rmondjone.xrecyclerview; + +import android.animation.ValueAnimator; +import android.content.Context; +import android.os.Handler; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.animation.Animation; +import android.view.animation.RotateAnimation; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.rmondjone.xrecyclerview.progressindicator.AVLoadingIndicatorView; +import com.rmondjone.locktableview.R; + +import java.util.Date; + +public class ArrowRefreshHeader extends LinearLayout implements BaseRefreshHeader { + + private LinearLayout mContainer; + private ImageView mArrowImageView; + private SimpleViewSwitcher mProgressBar; + private TextView mStatusTextView; + private int mState = STATE_NORMAL; + + private TextView mHeaderTimeView; + + private Animation mRotateUpAnim; + private Animation mRotateDownAnim; + + private static final int ROTATE_ANIM_DURATION = 180; + + public int mMeasuredHeight; + + public ArrowRefreshHeader(Context context) { + super(context); + initView(); + } + + /** + * @param context + * @param attrs + */ + public ArrowRefreshHeader(Context context, AttributeSet attrs) { + super(context, attrs); + initView(); + } + + private void initView() { + // 初始情况,设置下拉刷新view高度为0 + mContainer = (LinearLayout) LayoutInflater.from(getContext()).inflate( + R.layout.listview_header, null); + LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); + lp.setMargins(0, 0, 0, 0); + this.setLayoutParams(lp); + this.setPadding(0, 0, 0, 0); + + addView(mContainer, new LayoutParams(LayoutParams.MATCH_PARENT, 0)); + setGravity(Gravity.BOTTOM); + + mArrowImageView = (ImageView)findViewById(R.id.listview_header_arrow); + mStatusTextView = (TextView)findViewById(R.id.refresh_status_textview); + + //init the progress view + mProgressBar = (SimpleViewSwitcher)findViewById(R.id.listview_header_progressbar); + AVLoadingIndicatorView progressView = new AVLoadingIndicatorView(getContext()); + progressView.setIndicatorColor(0xffB5B5B5); + progressView.setIndicatorId(ProgressStyle.BallSpinFadeLoader); + mProgressBar.setView(progressView); + + + mRotateUpAnim = new RotateAnimation(0.0f, -180.0f, + Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); + mRotateUpAnim.setDuration(ROTATE_ANIM_DURATION); + mRotateUpAnim.setFillAfter(true); + mRotateDownAnim = new RotateAnimation(-180.0f, 0.0f, + Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); + mRotateDownAnim.setDuration(ROTATE_ANIM_DURATION); + mRotateDownAnim.setFillAfter(true); + + mHeaderTimeView = (TextView)findViewById(R.id.last_refresh_time); + measure(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT); + mMeasuredHeight = getMeasuredHeight(); + } + + public void setProgressStyle(int style) { + if(style == ProgressStyle.SysProgress){ + mProgressBar.setView(new ProgressBar(getContext(), null, android.R.attr.progressBarStyle)); + }else{ + AVLoadingIndicatorView progressView = new AVLoadingIndicatorView(this.getContext()); + progressView.setIndicatorColor(0xffB5B5B5); + progressView.setIndicatorId(style); + mProgressBar.setView(progressView); + } + } + + public void setArrowImageView(int resid){ + mArrowImageView.setImageResource(resid); + } + + public void setState(int state) { + if (state == mState) return ; + + if (state == STATE_REFRESHING) { // 显示进度 + mArrowImageView.clearAnimation(); + mArrowImageView.setVisibility(View.INVISIBLE); + mProgressBar.setVisibility(View.VISIBLE); + smoothScrollTo(mMeasuredHeight); + } else if(state == STATE_DONE) { + mArrowImageView.setVisibility(View.INVISIBLE); + mProgressBar.setVisibility(View.INVISIBLE); + } else { // 显示箭头图片 + mArrowImageView.setVisibility(View.VISIBLE); + mProgressBar.setVisibility(View.INVISIBLE); + } + + switch(state){ + case STATE_NORMAL: + if (mState == STATE_RELEASE_TO_REFRESH) { + mArrowImageView.startAnimation(mRotateDownAnim); + } + if (mState == STATE_REFRESHING) { + mArrowImageView.clearAnimation(); + } + mStatusTextView.setText(R.string.listview_header_hint_normal); + break; + case STATE_RELEASE_TO_REFRESH: + if (mState != STATE_RELEASE_TO_REFRESH) { + mArrowImageView.clearAnimation(); + mArrowImageView.startAnimation(mRotateUpAnim); + mStatusTextView.setText(R.string.listview_header_hint_release); + } + break; + case STATE_REFRESHING: + mStatusTextView.setText(R.string.refreshing); + break; + case STATE_DONE: + mStatusTextView.setText(R.string.refresh_done); + break; + default: + } + + mState = state; + } + + public int getState() { + return mState; + } + + @Override + public void refreshComplete(){ + mHeaderTimeView.setText(friendlyTime(new Date())); + setState(STATE_DONE); + new Handler().postDelayed(new Runnable(){ + public void run() { + reset(); + } + }, 200); + } + + public void setVisibleHeight(int height) { + if (height < 0) height = 0; + LayoutParams lp = (LayoutParams) mContainer .getLayoutParams(); + lp.height = height; + mContainer.setLayoutParams(lp); + } + + public int getVisibleHeight() { + LayoutParams lp = (LayoutParams) mContainer.getLayoutParams(); + return lp.height; + } + + @Override + public void onMove(float delta) { + if(getVisibleHeight() > 0 || delta > 0) { + setVisibleHeight((int) delta + getVisibleHeight()); + if (mState <= STATE_RELEASE_TO_REFRESH) { // 未处于刷新状态,更新箭头 + if (getVisibleHeight() > mMeasuredHeight) { + setState(STATE_RELEASE_TO_REFRESH); + }else { + setState(STATE_NORMAL); + } + } + } + } + + @Override + public boolean releaseAction() { + boolean isOnRefresh = false; + int height = getVisibleHeight(); + if (height == 0) // not visible. + isOnRefresh = false; + + if(getVisibleHeight() > mMeasuredHeight && mState < STATE_REFRESHING){ + setState(STATE_REFRESHING); + isOnRefresh = true; + } + // refreshing and header isn't shown fully. do nothing. + if (mState == STATE_REFRESHING && height <= mMeasuredHeight) { +// return false; + } + if (mState != STATE_REFRESHING) { + smoothScrollTo(0); + } + + if (mState == STATE_REFRESHING) { + int destHeight = mMeasuredHeight; + smoothScrollTo(destHeight); + } + + return isOnRefresh; + } + + public void reset() { + smoothScrollTo(0); + new Handler().postDelayed(new Runnable() { + public void run() { + setState(STATE_NORMAL); + } + }, 500); + } + + private void smoothScrollTo(int destHeight) { + ValueAnimator animator = ValueAnimator.ofInt(getVisibleHeight(), destHeight); + animator.setDuration(300).start(); + animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) + { + setVisibleHeight((int) animation.getAnimatedValue()); + } + }); + animator.start(); + } + + public static String friendlyTime(Date time) { + //获取time距离当前的秒数 + int ct = (int)((System.currentTimeMillis() - time.getTime())/1000); + + if(ct == 0) { + return "刚刚"; + } + + if(ct > 0 && ct < 60) { + return ct + "秒前"; + } + + if(ct >= 60 && ct < 3600) { + return Math.max(ct / 60,1) + "分钟前"; + } + if(ct >= 3600 && ct < 86400) + return ct / 3600 + "小时前"; + if(ct >= 86400 && ct < 2592000){ //86400 * 30 + int day = ct / 86400 ; + return day + "天前"; + } + if(ct >= 2592000 && ct < 31104000) { //86400 * 30 + return ct / 2592000 + "月前"; + } + return ct / 31104000 + "年前"; + } + +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/BaseRefreshHeader.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/BaseRefreshHeader.java new file mode 100644 index 00000000..98e537bb --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/BaseRefreshHeader.java @@ -0,0 +1,19 @@ +package com.rmondjone.xrecyclerview; + +/** + * Created by jianghejie on 15/11/22. + */ +interface BaseRefreshHeader { + + int STATE_NORMAL = 0; + int STATE_RELEASE_TO_REFRESH = 1; + int STATE_REFRESHING = 2; + int STATE_DONE = 3; + + void onMove(float delta); + + boolean releaseAction(); + + void refreshComplete(); + +} \ No newline at end of file diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/ItemTouchHelperAdapter.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/ItemTouchHelperAdapter.java new file mode 100644 index 00000000..dcd75931 --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/ItemTouchHelperAdapter.java @@ -0,0 +1,38 @@ +package com.rmondjone.xrecyclerview; + + +/** + * Created by jianghejie on 16/6/20. + */ + +public interface ItemTouchHelperAdapter { + + /** + * Called when an item has been dragged far enough to trigger a move. This is called every time + * an item is shifted, and not at the end of a "drop" event.
+ *
+ * Implementations should call {@link RecyclerView.Adapter#notifyItemMoved(int, int)} after + * adjusting the underlying data to reflect this move. + * + * @param fromPosition The start position of the moved item. + * @param toPosition Then resolved position of the moved item. + * + * @see RecyclerView#getAdapterPositionFor(RecyclerView.ViewHolder) + * @see RecyclerView.ViewHolder#getAdapterPosition() + */ + void onItemMove(int fromPosition, int toPosition); + + + /** + * Called when an item has been dismissed by a swipe.
+ *
+ * Implementations should call {@link RecyclerView.Adapter#notifyItemRemoved(int)} after + * adjusting the underlying data to reflect this removal. + * + * @param position The position of the item dismissed. + * + * @see RecyclerView#getAdapterPositionFor(RecyclerView.ViewHolder) + * @see RecyclerView.ViewHolder#getAdapterPosition() + */ + void onItemDismiss(int position); +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/JellyView.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/JellyView.java new file mode 100644 index 00000000..27e2fb0a --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/JellyView.java @@ -0,0 +1,108 @@ +package com.rmondjone.xrecyclerview; + +/** + * Created by jianghejie on 15/11/22. + */ + +import android.annotation.TargetApi; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Path; +import android.os.Build; +import android.util.AttributeSet; +import android.util.Log; +import android.view.View; + + +public class JellyView extends View implements BaseRefreshHeader{ + Path path; + + Paint paint; + + private int minimumHeight = 0; + + private int jellyHeight =0; + + public JellyView(Context context) { + super(context); + init(); + } + + public JellyView(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public JellyView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(); + } + + @SuppressWarnings("unused") + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + public JellyView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + init(); + } + + private void init() { + if (isInEditMode()) { + return; + } + path = new Path(); + paint = new Paint(); + paint.setColor(getContext().getResources().getColor(android.R.color.holo_blue_bright)); + paint.setAntiAlias(true); + } + + public void setJellyColor(int jellyColor) { + paint.setColor(jellyColor); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + path.reset(); + path.lineTo(0, minimumHeight); + path.quadTo(getMeasuredWidth() / 2, minimumHeight + jellyHeight, getMeasuredWidth(), minimumHeight); + path.lineTo(getMeasuredWidth(), 0); + canvas.drawPath(path, paint); + } + + @Override + public void setMinimumHeight(int minimumHeight) { + this.minimumHeight = minimumHeight; + } + + public void setJellyHeight(int ribbonHeight) { + this.jellyHeight = ribbonHeight; + } + + @Override + public int getMinimumHeight() { + return minimumHeight; + } + + public int getJellyHeight() { + return jellyHeight; + } + + + @Override + public void refreshComplete(){ + + } + + @Override + public void onMove(float delta) { + jellyHeight = jellyHeight + (int)delta; + Log.i("jellyHeight", "delta = " + delta); + this.invalidate(); + } + + @Override + public boolean releaseAction() { + return false; + } +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/LoadingMoreFooter.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/LoadingMoreFooter.java new file mode 100644 index 00000000..34b60fc5 --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/LoadingMoreFooter.java @@ -0,0 +1,108 @@ +package com.rmondjone.xrecyclerview; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import androidx.recyclerview.widget.RecyclerView; +import com.rmondjone.xrecyclerview.progressindicator.AVLoadingIndicatorView; +import com.rmondjone.locktableview.R; + +public class LoadingMoreFooter extends LinearLayout { + + private SimpleViewSwitcher progressCon; + public final static int STATE_LOADING = 0; + public final static int STATE_COMPLETE = 1; + public final static int STATE_NOMORE = 2; + private TextView mText; + private String loadingHint; + private String noMoreHint; + private String loadingDoneHint; + + public LoadingMoreFooter(Context context) { + super(context); + initView(); + } + + /** + * @param context + * @param attrs + */ + public LoadingMoreFooter(Context context, AttributeSet attrs) { + super(context, attrs); + initView(); + } + + public void setLoadingHint(String hint) { + loadingHint = hint; + } + + public void setNoMoreHint(String hint) { + noMoreHint = hint; + } + + public void setLoadingDoneHint(String hint) { + loadingDoneHint = hint; + } + + public void initView(){ + setGravity(Gravity.CENTER); + setLayoutParams(new RecyclerView.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + progressCon = new SimpleViewSwitcher(getContext()); + progressCon.setLayoutParams(new ViewGroup.LayoutParams( + ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + + AVLoadingIndicatorView progressView = new AVLoadingIndicatorView(this.getContext()); + progressView.setIndicatorColor(0xffB5B5B5); + progressView.setIndicatorId(ProgressStyle.BallSpinFadeLoader); + progressCon.setView(progressView); + + addView(progressCon); + mText = new TextView(getContext()); + mText.setText("正在加载..."); + loadingHint = (String)getContext().getText(R.string.listview_loading); + noMoreHint = (String)getContext().getText(R.string.nomore_loading); + loadingDoneHint = (String)getContext().getText(R.string.loading_done); + LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + layoutParams.setMargins( (int)getResources().getDimension(R.dimen.textandiconmargin),0,0,0 ); + + mText.setLayoutParams(layoutParams); + addView(mText); + } + + public void setProgressStyle(int style) { + if(style == ProgressStyle.SysProgress){ + progressCon.setView(new ProgressBar(getContext(), null, android.R.attr.progressBarStyle)); + }else{ + AVLoadingIndicatorView progressView = new AVLoadingIndicatorView(this.getContext()); + progressView.setIndicatorColor(0xffB5B5B5); + progressView.setIndicatorId(style); + progressCon.setView(progressView); + } + } + + public void setState(int state) { + switch(state) { + case STATE_LOADING: + progressCon.setVisibility(View.VISIBLE); + mText.setText(loadingHint); + this.setVisibility(View.VISIBLE); + break; + case STATE_COMPLETE: + mText.setText(loadingDoneHint); + this.setVisibility(View.GONE); + break; + case STATE_NOMORE: + mText.setText(noMoreHint); + progressCon.setVisibility(View.GONE); + this.setVisibility(View.VISIBLE); + break; + } + } +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/ProgressStyle.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/ProgressStyle.java new file mode 100644 index 00000000..7b1b551d --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/ProgressStyle.java @@ -0,0 +1,36 @@ +package com.rmondjone.xrecyclerview; + +/** + * Created by jianghejie on 15/11/23. + */ +public class ProgressStyle { + public static final int SysProgress=-1; + public static final int BallPulse=0; + public static final int BallGridPulse=1; + public static final int BallClipRotate=2; + public static final int BallClipRotatePulse=3; + public static final int SquareSpin=4; + public static final int BallClipRotateMultiple=5; + public static final int BallPulseRise=6; + public static final int BallRotate=7; + public static final int CubeTransition=8; + public static final int BallZigZag=9; + public static final int BallZigZagDeflect=10; + public static final int BallTrianglePath=11; + public static final int BallScale=12; + public static final int LineScale=13; + public static final int LineScaleParty=14; + public static final int BallScaleMultiple=15; + public static final int BallPulseSync=16; + public static final int BallBeat=17; + public static final int LineScalePulseOut=18; + public static final int LineScalePulseOutRapid=19; + public static final int BallScaleRipple=20; + public static final int BallScaleRippleMultiple=21; + public static final int BallSpinFadeLoader=22; + public static final int LineSpinFadeLoader=23; + public static final int TriangleSkewSpin=24; + public static final int Pacman=25; + public static final int BallGridBeat=26; + public static final int SemiCircleSpin=27; +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/SimpleItemTouchHelperCallback.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/SimpleItemTouchHelperCallback.java new file mode 100644 index 00000000..1756c63c --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/SimpleItemTouchHelperCallback.java @@ -0,0 +1,88 @@ +package com.rmondjone.xrecyclerview; + +import android.graphics.Canvas; +import android.graphics.Color; +import android.view.View; + +import androidx.recyclerview.widget.ItemTouchHelper; +import androidx.recyclerview.widget.RecyclerView; + +/** + * Created by jianghejie on 16/6/20. + */ + +public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback { + + public static final float ALPHA_FULL = 1.0f; + + private final ItemTouchHelperAdapter mAdapter; + private XRecyclerView mXrecyclerView; + + public SimpleItemTouchHelperCallback(ItemTouchHelperAdapter adapter, XRecyclerView recyclerView) { + mAdapter = adapter; + this.mXrecyclerView = recyclerView; + } + + @Override + public boolean isLongPressDragEnabled() { + return true; + } + + @Override + public boolean isItemViewSwipeEnabled() { + return true; + } + + @Override + public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { + // Enable drag and swipe in both directions + final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN; + final int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END; + return makeMovementFlags(dragFlags, swipeFlags); + } + + @Override + public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) { + if (source.getItemViewType() != target.getItemViewType()) { + return false; + } + // Notify the adapter of the move + mAdapter.onItemMove(source.getAdapterPosition(), target.getAdapterPosition()); + return true; + } + + @Override + public void onSwiped(RecyclerView.ViewHolder viewHolder, int i) { + // Notify the adapter of the dismissal + mAdapter.onItemDismiss(viewHolder.getAdapterPosition()); + } + + @Override + public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { + super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); + + // Fade out the view as it is swiped out of the parent's bounds + if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) { + View itemView = viewHolder.itemView; + final float alpha = ALPHA_FULL - Math.abs(dX) / (float) itemView.getWidth(); + itemView.setAlpha(alpha); + } + } + + @Override + public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) { + if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) { + // Let the view holder know that this item is being moved or dragged + viewHolder.itemView.setBackgroundColor(Color.LTGRAY); + } + + super.onSelectedChanged(viewHolder, actionState); + } + + @Override + public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { + super.clearView(recyclerView, viewHolder); + viewHolder.itemView.setAlpha(ALPHA_FULL); + viewHolder.itemView.setBackgroundColor(0); + } +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/SimpleViewSwitcher.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/SimpleViewSwitcher.java new file mode 100644 index 00000000..e0da4522 --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/SimpleViewSwitcher.java @@ -0,0 +1,60 @@ +package com.rmondjone.xrecyclerview; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewGroup; + +/** + * Created by jianghejie on 15/11/22. + */ +public class SimpleViewSwitcher extends ViewGroup { + + public SimpleViewSwitcher(Context context) { + super(context); + } + + public SimpleViewSwitcher(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public SimpleViewSwitcher(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int childCount = this.getChildCount(); + int maxHeight = 0; + int maxWidth = 0; + for (int i = 0; i < childCount; i++) { + View child = this.getChildAt(i); + this.measureChild(child, widthMeasureSpec, heightMeasureSpec); + int cw = child.getMeasuredWidth(); + // int ch = child.getMeasuredHeight(); + maxWidth = child.getMeasuredWidth(); + maxHeight = child.getMeasuredHeight(); + } + setMeasuredDimension(maxWidth, maxHeight); + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + final int count = getChildCount(); + for (int i = 0; i < count; i++) { + final View child = getChildAt(i); + if (child.getVisibility() != View.GONE) { + child.layout(0, 0, r - l, b - t); + + } + } + } + + public void setView(View view) { + if (this.getChildCount() != 0){ + this.removeViewAt(0); + } + this.addView(view,0); + } + +} \ No newline at end of file diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/XRecyclerView.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/XRecyclerView.java new file mode 100644 index 00000000..cac6025d --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/XRecyclerView.java @@ -0,0 +1,775 @@ +package com.rmondjone.xrecyclerview; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewParent; + +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.recyclerview.widget.StaggeredGridLayoutManager; + +import com.google.android.material.appbar.AppBarLayout; + +import java.util.ArrayList; +import java.util.List; + +public class XRecyclerView extends RecyclerView { + private boolean isLoadingData = false; + private boolean isNoMore = false; + private int mRefreshProgressStyle = ProgressStyle.SysProgress; + private int mLoadingMoreProgressStyle = ProgressStyle.SysProgress; + private ArrayList mHeaderViews = new ArrayList<>(); + private WrapAdapter mWrapAdapter; + private float mLastY = -1; + private static final float DRAG_RATE = 3; + private LoadingListener mLoadingListener; + private ArrowRefreshHeader mRefreshHeader; + private boolean pullRefreshEnabled = true; + private boolean loadingMoreEnabled = true; + //下面的ItemViewType是保留值(ReservedItemViewType),如果用户的adapter与它们重复将会强制抛出异常。不过为了简化,我们检测到重复时对用户的提示是ItemViewType必须小于10000 + private static final int TYPE_REFRESH_HEADER = 10000;//设置一个很大的数字,尽可能避免和用户的adapter冲突 + private static final int TYPE_FOOTER = 10001; + private static final int HEADER_INIT_INDEX = 10002; + private static List sHeaderTypes = new ArrayList<>();//每个header必须有不同的type,不然滚动的时候顺序会变化 + private int mPageCount = 0; + //adapter没有数据的时候显示,类似于listView的emptyView + private View mEmptyView; + private View mFootView; + private final RecyclerView.AdapterDataObserver mDataObserver = new DataObserver(); + private AppBarStateChangeListener.State appbarState = AppBarStateChangeListener.State.EXPANDED; + + public XRecyclerView(Context context) { + this(context, null); + } + + public XRecyclerView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public XRecyclerView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(); + } + + private void init() { + if (pullRefreshEnabled) { + mRefreshHeader = new ArrowRefreshHeader(getContext()); + mRefreshHeader.setProgressStyle(mRefreshProgressStyle); + } + LoadingMoreFooter footView = new LoadingMoreFooter(getContext()); + footView.setProgressStyle(mLoadingMoreProgressStyle); + mFootView = footView; + mFootView.setVisibility(GONE); + } + + public void setFootViewText(String loading, String noMore) { + if (mFootView instanceof LoadingMoreFooter) { + ((LoadingMoreFooter) mFootView).setLoadingHint(loading); + ((LoadingMoreFooter) mFootView).setNoMoreHint(noMore); + } + } + + public void addHeaderView(View view) { + sHeaderTypes.add(HEADER_INIT_INDEX + mHeaderViews.size()); + mHeaderViews.add(view); + if (mWrapAdapter != null) { + mWrapAdapter.notifyDataSetChanged(); + } + } + + //根据header的ViewType判断是哪个header + private View getHeaderViewByType(int itemType) { + if (!isHeaderType(itemType)) { + return null; + } + return mHeaderViews.get(itemType - HEADER_INIT_INDEX); + } + + //判断一个type是否为HeaderType + private boolean isHeaderType(int itemViewType) { + return mHeaderViews.size() > 0 && sHeaderTypes.contains(itemViewType); + } + + //判断是否是XRecyclerView保留的itemViewType + private boolean isReservedItemViewType(int itemViewType) { + if (itemViewType == TYPE_REFRESH_HEADER || itemViewType == TYPE_FOOTER || sHeaderTypes.contains(itemViewType)) { + return true; + } else { + return false; + } + } + + public void setFootView(final View view) { + mFootView = view; + } + + public void loadMoreComplete() { + isLoadingData = false; + if (mFootView instanceof LoadingMoreFooter) { + ((LoadingMoreFooter) mFootView).setState(LoadingMoreFooter.STATE_COMPLETE); + } else { + mFootView.setVisibility(View.GONE); + } + } + + public void setNoMore(boolean noMore) { + isLoadingData = false; + isNoMore = noMore; + if (mFootView instanceof LoadingMoreFooter) { + ((LoadingMoreFooter) mFootView).setState(isNoMore ? LoadingMoreFooter.STATE_NOMORE : LoadingMoreFooter.STATE_COMPLETE); + } else { + mFootView.setVisibility(View.GONE); + } + } + + public void refresh() { + if (pullRefreshEnabled && mLoadingListener != null) { + mRefreshHeader.setState(ArrowRefreshHeader.STATE_REFRESHING); + mLoadingListener.onRefresh(); + } + } + + public void reset() { + setNoMore(false); + loadMoreComplete(); + refreshComplete(); + } + + public void refreshComplete() { + mRefreshHeader.refreshComplete(); + setNoMore(false); + } + + public void setRefreshHeader(ArrowRefreshHeader refreshHeader) { + mRefreshHeader = refreshHeader; + } + + public void setPullRefreshEnabled(boolean enabled) { + pullRefreshEnabled = enabled; + } + + public void setLoadingMoreEnabled(boolean enabled) { + loadingMoreEnabled = enabled; + if (!enabled) { + if (mFootView instanceof LoadingMoreFooter) { + ((LoadingMoreFooter) mFootView).setState(LoadingMoreFooter.STATE_COMPLETE); + } + } + } + + public void setRefreshProgressStyle(int style) { + mRefreshProgressStyle = style; + if (mRefreshHeader != null) { + mRefreshHeader.setProgressStyle(style); + } + } + + public void setLoadingMoreProgressStyle(int style) { + mLoadingMoreProgressStyle = style; + if (mFootView instanceof LoadingMoreFooter) { + ((LoadingMoreFooter) mFootView).setProgressStyle(style); + } + } + + public void setArrowImageView(int resId) { + if (mRefreshHeader != null) { + mRefreshHeader.setArrowImageView(resId); + } + } + + public void setEmptyView(View emptyView) { + this.mEmptyView = emptyView; + mDataObserver.onChanged(); + } + + public View getEmptyView() { + return mEmptyView; + } + + @Override + public void setAdapter(Adapter adapter) { + mWrapAdapter = new WrapAdapter(adapter); + super.setAdapter(mWrapAdapter); + adapter.registerAdapterDataObserver(mDataObserver); + mDataObserver.onChanged(); + } + + //避免用户自己调用getAdapter() 引起的ClassCastException + @Override + public Adapter getAdapter() { + if (mWrapAdapter != null) + return mWrapAdapter.getOriginalAdapter(); + else + return null; + } + + @Override + public void setLayoutManager(LayoutManager layout) { + super.setLayoutManager(layout); + if (mWrapAdapter != null) { + if (layout instanceof GridLayoutManager) { + final GridLayoutManager gridManager = ((GridLayoutManager) layout); + gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { + @Override + public int getSpanSize(int position) { + return (mWrapAdapter.isHeader(position) || mWrapAdapter.isFooter(position) || mWrapAdapter.isRefreshHeader(position)) + ? gridManager.getSpanCount() : 1; + } + }); + + } + } + } + + @Override + public void onScrollStateChanged(int state) { + super.onScrollStateChanged(state); + if (state == RecyclerView.SCROLL_STATE_IDLE && mLoadingListener != null && !isLoadingData && loadingMoreEnabled) { + LayoutManager layoutManager = getLayoutManager(); + int lastVisibleItemPosition; + if (layoutManager instanceof GridLayoutManager) { + lastVisibleItemPosition = ((GridLayoutManager) layoutManager).findLastVisibleItemPosition(); + } else if (layoutManager instanceof StaggeredGridLayoutManager) { + int[] into = new int[((StaggeredGridLayoutManager) layoutManager).getSpanCount()]; + ((StaggeredGridLayoutManager) layoutManager).findLastVisibleItemPositions(into); + lastVisibleItemPosition = findMax(into); + } else { + lastVisibleItemPosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition(); + } + + if (layoutManager.getChildCount() > 0 + && lastVisibleItemPosition >= layoutManager.getItemCount() - 1 + //因为我的控件里layoutManager.getItemCount()永远等于1(item),layoutManager.getChildCount() + //永远等于2(刷新头和item),所以这个条件永远不成立,永远调不了上拉加载事件,需要注释掉 + //&& layoutManager.getItemCount() > layoutManager.getChildCount() + && !isNoMore + && mRefreshHeader.getState() < ArrowRefreshHeader.STATE_REFRESHING + //只有当更多底部视图显示在页面上才开始进行加载更多数据 + &&lastVisibleItemPosition>=2) { + isLoadingData = true; + if (mFootView instanceof LoadingMoreFooter) { + ((LoadingMoreFooter) mFootView).setState(LoadingMoreFooter.STATE_LOADING); + } else { + mFootView.setVisibility(View.VISIBLE); + } + mLoadingListener.onLoadMore(); + } + } + } + + @Override + public boolean onTouchEvent(MotionEvent ev) { + if (mLastY == -1) { + mLastY = ev.getRawY(); + } + switch (ev.getAction()) { + case MotionEvent.ACTION_DOWN: + mLastY = ev.getRawY(); + break; + case MotionEvent.ACTION_MOVE: + final float deltaY = ev.getRawY() - mLastY; + mLastY = ev.getRawY(); + if (isOnTop() && pullRefreshEnabled && appbarState == AppBarStateChangeListener.State.EXPANDED) { + mRefreshHeader.onMove(deltaY / DRAG_RATE); + if (mRefreshHeader.getVisibleHeight() > 0 && mRefreshHeader.getState() < ArrowRefreshHeader.STATE_REFRESHING) { + return false; + } + } + break; + default: + mLastY = -1; // reset + if (isOnTop() && pullRefreshEnabled && appbarState == AppBarStateChangeListener.State.EXPANDED) { + if (mRefreshHeader.releaseAction()) { + if (mLoadingListener != null) { + mLoadingListener.onRefresh(); + } + } + } + break; + } + return super.onTouchEvent(ev); + } + + private int findMax(int[] lastPositions) { + int max = lastPositions[0]; + for (int value : lastPositions) { + if (value > max) { + max = value; + } + } + return max; + } + + private boolean isOnTop() { + if (mRefreshHeader.getParent() != null) { + return true; + } else { + return false; + } + } + + private class DataObserver extends RecyclerView.AdapterDataObserver { + @Override + public void onChanged() { + if (mWrapAdapter != null) { + mWrapAdapter.notifyDataSetChanged(); + } + if (mWrapAdapter != null && mEmptyView != null) { + int emptyCount = 1 + mWrapAdapter.getHeadersCount(); + if (loadingMoreEnabled) { + emptyCount++; + } + if (mWrapAdapter.getItemCount() == emptyCount) { + mEmptyView.setVisibility(View.VISIBLE); + XRecyclerView.this.setVisibility(View.GONE); + } else { + + mEmptyView.setVisibility(View.GONE); + XRecyclerView.this.setVisibility(View.VISIBLE); + } + } + } + + @Override + public void onItemRangeInserted(int positionStart, int itemCount) { + mWrapAdapter.notifyItemRangeInserted(positionStart, itemCount); + } + + @Override + public void onItemRangeChanged(int positionStart, int itemCount) { + mWrapAdapter.notifyItemRangeChanged(positionStart, itemCount); + } + + @Override + public void onItemRangeChanged(int positionStart, int itemCount, Object payload) { + mWrapAdapter.notifyItemRangeChanged(positionStart, itemCount, payload); + } + + @Override + public void onItemRangeRemoved(int positionStart, int itemCount) { + mWrapAdapter.notifyItemRangeRemoved(positionStart, itemCount); + } + + @Override + public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) { + mWrapAdapter.notifyItemMoved(fromPosition, toPosition); + } + } + + ; + + private class WrapAdapter extends RecyclerView.Adapter { + + private RecyclerView.Adapter adapter; + + public WrapAdapter(RecyclerView.Adapter adapter) { + this.adapter = adapter; + } + + public RecyclerView.Adapter getOriginalAdapter() { + return this.adapter; + } + + public boolean isHeader(int position) { + return position >= 1 && position < mHeaderViews.size() + 1; + } + + public boolean isFooter(int position) { + if (loadingMoreEnabled) { + return position == getItemCount() - 1; + } else { + return false; + } + } + + public boolean isRefreshHeader(int position) { + return position == 0; + } + + public int getHeadersCount() { + return mHeaderViews.size(); + } + + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + if (viewType == TYPE_REFRESH_HEADER) { + return new SimpleViewHolder(mRefreshHeader); + } else if (isHeaderType(viewType)) { + return new SimpleViewHolder(getHeaderViewByType(viewType)); + } else if (viewType == TYPE_FOOTER) { + return new SimpleViewHolder(mFootView); + } + return adapter.onCreateViewHolder(parent, viewType); + } + + @Override + public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { + if (isHeader(position) || isRefreshHeader(position)) { + return; + } + int adjPosition = position - (getHeadersCount() + 1); + int adapterCount; + if (adapter != null) { + adapterCount = adapter.getItemCount(); + if (adjPosition < adapterCount) { + adapter.onBindViewHolder(holder, adjPosition); + } + } + } + + // some times we need to override this + @Override + public void onBindViewHolder(RecyclerView.ViewHolder holder, int position, List payloads) { + if (isHeader(position) || isRefreshHeader(position)) { + return; + } + int adjPosition = position - (getHeadersCount() + 1); + int adapterCount; + if (adapter != null) { + adapterCount = adapter.getItemCount(); + if (adjPosition < adapterCount) { + if (payloads.isEmpty()) { + adapter.onBindViewHolder(holder, adjPosition); + } else { + adapter.onBindViewHolder(holder, adjPosition, payloads); + } + } + } + } + + @Override + public int getItemCount() { + if (loadingMoreEnabled) { + if (adapter != null) { + return getHeadersCount() + adapter.getItemCount() + 2; + } else { + return getHeadersCount() + 2; + } + } else { + if (adapter != null) { + return getHeadersCount() + adapter.getItemCount() + 1; + } else { + return getHeadersCount() + 1; + } + } + } + + @Override + public int getItemViewType(int position) { + int adjPosition = position - (getHeadersCount() + 1); + if (isRefreshHeader(position)) { + return TYPE_REFRESH_HEADER; + } + if (isHeader(position)) { + position = position - 1; + return sHeaderTypes.get(position); + } + if (isFooter(position)) { + return TYPE_FOOTER; + } + int adapterCount; + if (adapter != null) { + adapterCount = adapter.getItemCount(); + if (adjPosition < adapterCount) { + int type = adapter.getItemViewType(adjPosition); + if (isReservedItemViewType(type)) { + throw new IllegalStateException("XRecyclerView require itemViewType in adapter should be less than 10000 "); + } + return type; + } + } + return 0; + } + + @Override + public long getItemId(int position) { + if (adapter != null && position >= getHeadersCount() + 1) { + int adjPosition = position - (getHeadersCount() + 1); + if (adjPosition < adapter.getItemCount()) { + return adapter.getItemId(adjPosition); + } + } + return -1; + } + + @Override + public void onAttachedToRecyclerView(RecyclerView recyclerView) { + super.onAttachedToRecyclerView(recyclerView); + RecyclerView.LayoutManager manager = recyclerView.getLayoutManager(); + if (manager instanceof GridLayoutManager) { + final GridLayoutManager gridManager = ((GridLayoutManager) manager); + gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { + @Override + public int getSpanSize(int position) { + return (isHeader(position) || isFooter(position) || isRefreshHeader(position)) + ? gridManager.getSpanCount() : 1; + } + }); + } + adapter.onAttachedToRecyclerView(recyclerView); + } + + @Override + public void onDetachedFromRecyclerView(RecyclerView recyclerView) { + adapter.onDetachedFromRecyclerView(recyclerView); + } + + @Override + public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) { + super.onViewAttachedToWindow(holder); + ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams(); + if (lp != null + && lp instanceof StaggeredGridLayoutManager.LayoutParams + && (isHeader(holder.getLayoutPosition()) || isRefreshHeader(holder.getLayoutPosition()) || isFooter(holder.getLayoutPosition()))) { + StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp; + p.setFullSpan(true); + } + adapter.onViewAttachedToWindow(holder); + } + + @Override + public void onViewDetachedFromWindow(RecyclerView.ViewHolder holder) { + adapter.onViewDetachedFromWindow(holder); + } + + @Override + public void onViewRecycled(RecyclerView.ViewHolder holder) { + adapter.onViewRecycled(holder); + } + + @Override + public boolean onFailedToRecycleView(RecyclerView.ViewHolder holder) { + return adapter.onFailedToRecycleView(holder); + } + + @Override + public void unregisterAdapterDataObserver(AdapterDataObserver observer) { + adapter.unregisterAdapterDataObserver(observer); + } + + @Override + public void registerAdapterDataObserver(AdapterDataObserver observer) { + adapter.registerAdapterDataObserver(observer); + } + + private class SimpleViewHolder extends RecyclerView.ViewHolder { + public SimpleViewHolder(View itemView) { + super(itemView); + } + } + } + + public void setLoadingListener(LoadingListener listener) { + mLoadingListener = listener; + } + + public interface LoadingListener { + + void onRefresh(); + + void onLoadMore(); + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + //解决和CollapsingToolbarLayout冲突的问题 + AppBarLayout appBarLayout = null; + ViewParent p = getParent(); + while (p != null) { + if (p instanceof CoordinatorLayout) { + break; + } + p = p.getParent(); + } + if (p instanceof CoordinatorLayout) { + CoordinatorLayout coordinatorLayout = (CoordinatorLayout) p; + final int childCount = coordinatorLayout.getChildCount(); + for (int i = childCount - 1; i >= 0; i--) { + final View child = coordinatorLayout.getChildAt(i); + if (child instanceof AppBarLayout) { + appBarLayout = (AppBarLayout) child; + break; + } + } + if (appBarLayout != null) { + appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() { + @Override + public void onStateChanged(AppBarLayout appBarLayout, State state) { + appbarState = state; + } + }); + } + } + } + + public class DividerItemDecoration extends RecyclerView.ItemDecoration { + + private Drawable mDivider; + private int mOrientation; + + /** + * Sole constructor. Takes in a {@link Drawable} to be used as the interior + * divider. + * + * @param divider A divider {@code Drawable} to be drawn on the RecyclerView + */ + public DividerItemDecoration(Drawable divider) { + mDivider = divider; + } + + /** + * Draws horizontal or vertical dividers onto the parent RecyclerView. + * + * @param canvas The {@link Canvas} onto which dividers will be drawn + * @param parent The RecyclerView onto which dividers are being added + * @param state The current RecyclerView.State of the RecyclerView + */ + @Override + public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) { + if (mOrientation == LinearLayoutManager.HORIZONTAL) { + drawHorizontalDividers(canvas, parent); + } else if (mOrientation == LinearLayoutManager.VERTICAL) { + drawVerticalDividers(canvas, parent); + } + } + + /** + * Determines the size and location of offsets between items in the parent + * RecyclerView. + * + * @param outRect The {@link Rect} of offsets to be added around the child + * view + * @param view The child view to be decorated with an offset + * @param parent The RecyclerView onto which dividers are being added + * @param state The current RecyclerView.State of the RecyclerView + */ + @Override + public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { + super.getItemOffsets(outRect, view, parent, state); + + if (parent.getChildAdapterPosition(view) <= mWrapAdapter.getHeadersCount() + 1) { + return; + } + mOrientation = ((LinearLayoutManager) parent.getLayoutManager()).getOrientation(); + if (mOrientation == LinearLayoutManager.HORIZONTAL) { + outRect.left = mDivider.getIntrinsicWidth(); + } else if (mOrientation == LinearLayoutManager.VERTICAL) { + outRect.top = mDivider.getIntrinsicHeight(); + } + } + + /** + * Adds dividers to a RecyclerView with a LinearLayoutManager or its + * subclass oriented horizontally. + * + * @param canvas The {@link Canvas} onto which horizontal dividers will be + * drawn + * @param parent The RecyclerView onto which horizontal dividers are being + * added + */ + private void drawHorizontalDividers(Canvas canvas, RecyclerView parent) { + int parentTop = parent.getPaddingTop(); + int parentBottom = parent.getHeight() - parent.getPaddingBottom(); + + int childCount = parent.getChildCount(); + for (int i = 0; i < childCount - 1; i++) { + View child = parent.getChildAt(i); + + RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); + + int parentLeft = child.getRight() + params.rightMargin; + int parentRight = parentLeft + mDivider.getIntrinsicWidth(); + + mDivider.setBounds(parentLeft, parentTop, parentRight, parentBottom); + mDivider.draw(canvas); + } + } + + /** + * Adds dividers to a RecyclerView with a LinearLayoutManager or its + * subclass oriented vertically. + * + * @param canvas The {@link Canvas} onto which vertical dividers will be + * drawn + * @param parent The RecyclerView onto which vertical dividers are being + * added + */ + private void drawVerticalDividers(Canvas canvas, RecyclerView parent) { + int parentLeft = parent.getPaddingLeft(); + int parentRight = parent.getWidth() - parent.getPaddingRight(); + + int childCount = parent.getChildCount(); + for (int i = 0; i < childCount - 1; i++) { + View child = parent.getChildAt(i); + + RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); + + int parentTop = child.getBottom() + params.bottomMargin; + int parentBottom = parentTop + mDivider.getIntrinsicHeight(); + + mDivider.setBounds(parentLeft, parentTop, parentRight, parentBottom); + mDivider.draw(canvas); + } + } + } + + /** + * add by LinGuanHong below + */ + private int scrollDyCounter = 0; + + @Override + public void scrollToPosition(int position) { + super.scrollToPosition(position); + /** if we scroll to position 0, the scrollDyCounter should be reset */ + if (position == 0) { + scrollDyCounter = 0; + } + } + + @Override + public void onScrolled(int dx, int dy) { + super.onScrolled(dx, dy); + if (scrollAlphaChangeListener == null) { + return; + } + int height = scrollAlphaChangeListener.setLimitHeight(); + scrollDyCounter = scrollDyCounter + dy; + if (scrollDyCounter <= 0) { + scrollAlphaChangeListener.onAlphaChange(0); + } else if (scrollDyCounter <= height && scrollDyCounter > 0) { + float scale = (float) scrollDyCounter / height; /** 255/height = x/255 */ + float alpha = (255 * scale); + scrollAlphaChangeListener.onAlphaChange((int) alpha); + } else { + scrollAlphaChangeListener.onAlphaChange(255); + } + } + + private ScrollAlphaChangeListener scrollAlphaChangeListener; + + public void setScrollAlphaChangeListener( + ScrollAlphaChangeListener scrollAlphaChangeListener + ) { + this.scrollAlphaChangeListener = scrollAlphaChangeListener; + } + + public interface ScrollAlphaChangeListener { + void onAlphaChange(int alpha); + + /** + * you can handle the alpha insert it + */ + int setLimitHeight(); /** set a height for the begging of the alpha start to change */ + } +} \ No newline at end of file diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/AVLoadingIndicatorView.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/AVLoadingIndicatorView.java new file mode 100644 index 00000000..657440fd --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/AVLoadingIndicatorView.java @@ -0,0 +1,365 @@ +package com.rmondjone.xrecyclerview.progressindicator; + +import android.annotation.TargetApi; +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.os.Build; +import android.util.AttributeSet; +import android.view.View; + +import androidx.annotation.IntDef; +import com.rmondjone.xrecyclerview.progressindicator.indicator.BallBeatIndicator; +import com.rmondjone.xrecyclerview.progressindicator.indicator.BallClipRotateIndicator; +import com.rmondjone.xrecyclerview.progressindicator.indicator.BallClipRotateMultipleIndicator; +import com.rmondjone.xrecyclerview.progressindicator.indicator.BallClipRotatePulseIndicator; +import com.rmondjone.xrecyclerview.progressindicator.indicator.BallGridBeatIndicator; +import com.rmondjone.xrecyclerview.progressindicator.indicator.BallGridPulseIndicator; +import com.rmondjone.xrecyclerview.progressindicator.indicator.BallPulseIndicator; +import com.rmondjone.xrecyclerview.progressindicator.indicator.BallPulseRiseIndicator; +import com.rmondjone.xrecyclerview.progressindicator.indicator.BallPulseSyncIndicator; +import com.rmondjone.xrecyclerview.progressindicator.indicator.BallRotateIndicator; +import com.rmondjone.xrecyclerview.progressindicator.indicator.BallScaleIndicator; +import com.rmondjone.xrecyclerview.progressindicator.indicator.BallScaleMultipleIndicator; +import com.rmondjone.xrecyclerview.progressindicator.indicator.BallScaleRippleIndicator; +import com.rmondjone.xrecyclerview.progressindicator.indicator.BallScaleRippleMultipleIndicator; +import com.rmondjone.xrecyclerview.progressindicator.indicator.BallSpinFadeLoaderIndicator; +import com.rmondjone.xrecyclerview.progressindicator.indicator.BallTrianglePathIndicator; +import com.rmondjone.xrecyclerview.progressindicator.indicator.BallZigZagDeflectIndicator; +import com.rmondjone.xrecyclerview.progressindicator.indicator.BallZigZagIndicator; +import com.rmondjone.xrecyclerview.progressindicator.indicator.BaseIndicatorController; +import com.rmondjone.xrecyclerview.progressindicator.indicator.CubeTransitionIndicator; +import com.rmondjone.xrecyclerview.progressindicator.indicator.LineScaleIndicator; +import com.rmondjone.xrecyclerview.progressindicator.indicator.LineScalePartyIndicator; +import com.rmondjone.xrecyclerview.progressindicator.indicator.LineScalePulseOutIndicator; +import com.rmondjone.xrecyclerview.progressindicator.indicator.LineScalePulseOutRapidIndicator; +import com.rmondjone.xrecyclerview.progressindicator.indicator.LineSpinFadeLoaderIndicator; +import com.rmondjone.xrecyclerview.progressindicator.indicator.PacmanIndicator; +import com.rmondjone.xrecyclerview.progressindicator.indicator.SemiCircleSpinIndicator; +import com.rmondjone.xrecyclerview.progressindicator.indicator.SquareSpinIndicator; +import com.rmondjone.xrecyclerview.progressindicator.indicator.TriangleSkewSpinIndicator; +import com.rmondjone.locktableview.R; + + +/** + * Created by Jack on 2015/10/15 + * + .BallPulse, + .BallGridPulse, + .BallClipRotate, + .BallClipRotatePulse, + .SquareSpin, + .BallClipRotateMultiple, + .BallPulseRise, + .BallRotate, + .CubeTransition, + .BallZigZag, + .BallZigZagDeflect, + .BallTrianglePath, + .BallScale, + .LineScale, + .LineScaleParty, + .BallScaleMultiple, + .BallPulseSync, + .BallBeat, + .LineScalePulseOut, + .LineScalePulseOutRapid, + .BallScaleRipple, + .BallScaleRippleMultiple, + .BallSpinFadeLoader, + .LineSpinFadeLoader, + .TriangleSkewSpin, + .Pacman, + .BallGridBeat, + .SemiCircleSpin + * + */ +public class AVLoadingIndicatorView extends View{ + //indicators + public static final int BallPulse=0; + public static final int BallGridPulse=1; + public static final int BallClipRotate=2; + public static final int BallClipRotatePulse=3; + public static final int SquareSpin=4; + public static final int BallClipRotateMultiple=5; + public static final int BallPulseRise=6; + public static final int BallRotate=7; + public static final int CubeTransition=8; + public static final int BallZigZag=9; + public static final int BallZigZagDeflect=10; + public static final int BallTrianglePath=11; + public static final int BallScale=12; + public static final int LineScale=13; + public static final int LineScaleParty=14; + public static final int BallScaleMultiple=15; + public static final int BallPulseSync=16; + public static final int BallBeat=17; + public static final int LineScalePulseOut=18; + public static final int LineScalePulseOutRapid=19; + public static final int BallScaleRipple=20; + public static final int BallScaleRippleMultiple=21; + public static final int BallSpinFadeLoader=22; + public static final int LineSpinFadeLoader=23; + public static final int TriangleSkewSpin=24; + public static final int Pacman=25; + public static final int BallGridBeat=26; + public static final int SemiCircleSpin=27; + + + @IntDef(flag = true, + value = { + BallPulse, + BallGridPulse, + BallClipRotate, + BallClipRotatePulse, + SquareSpin, + BallClipRotateMultiple, + BallPulseRise, + BallRotate, + CubeTransition, + BallZigZag, + BallZigZagDeflect, + BallTrianglePath, + BallScale, + LineScale, + LineScaleParty, + BallScaleMultiple, + BallPulseSync, + BallBeat, + LineScalePulseOut, + LineScalePulseOutRapid, + BallScaleRipple, + BallScaleRippleMultiple, + BallSpinFadeLoader, + LineSpinFadeLoader, + TriangleSkewSpin, + Pacman, + BallGridBeat, + SemiCircleSpin + }) + public @interface Indicator{} + + //Sizes (with defaults in DP) + public static final int DEFAULT_SIZE=30; + + //attrs + int mIndicatorId; + int mIndicatorColor; + + Paint mPaint; + + BaseIndicatorController mIndicatorController; + + private boolean mHasAnimation; + + public AVLoadingIndicatorView(Context context) { + super(context); + init(null, 0); + } + + public AVLoadingIndicatorView(Context context, AttributeSet attrs) { + super(context, attrs); + init(attrs, 0); + } + + public AVLoadingIndicatorView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(attrs, defStyleAttr); + } + + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + public AVLoadingIndicatorView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + init(attrs, defStyleAttr); + } + + private void init(AttributeSet attrs, int defStyle) { + TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.AVLoadingIndicatorView); + mIndicatorId=a.getInt(R.styleable.AVLoadingIndicatorView_indicator, BallPulse); + mIndicatorColor=a.getColor(R.styleable.AVLoadingIndicatorView_indicator_color, Color.WHITE); + a.recycle(); + mPaint=new Paint(); + mPaint.setColor(mIndicatorColor); + mPaint.setStyle(Paint.Style.FILL); + mPaint.setAntiAlias(true); + applyIndicator(); + } + + public void setIndicatorId(int indicatorId){ + mIndicatorId = indicatorId; + applyIndicator(); + } + + public void setIndicatorColor(int color){ + mIndicatorColor = color; + mPaint.setColor(mIndicatorColor); + this.invalidate(); + } + + private void applyIndicator(){ + switch (mIndicatorId){ + case BallPulse: + mIndicatorController=new BallPulseIndicator(); + break; + case BallGridPulse: + mIndicatorController=new BallGridPulseIndicator(); + break; + case BallClipRotate: + mIndicatorController=new BallClipRotateIndicator(); + break; + case BallClipRotatePulse: + mIndicatorController=new BallClipRotatePulseIndicator(); + break; + case SquareSpin: + mIndicatorController=new SquareSpinIndicator(); + break; + case BallClipRotateMultiple: + mIndicatorController=new BallClipRotateMultipleIndicator(); + break; + case BallPulseRise: + mIndicatorController=new BallPulseRiseIndicator(); + break; + case BallRotate: + mIndicatorController=new BallRotateIndicator(); + break; + case CubeTransition: + mIndicatorController=new CubeTransitionIndicator(); + break; + case BallZigZag: + mIndicatorController=new BallZigZagIndicator(); + break; + case BallZigZagDeflect: + mIndicatorController=new BallZigZagDeflectIndicator(); + break; + case BallTrianglePath: + mIndicatorController=new BallTrianglePathIndicator(); + break; + case BallScale: + mIndicatorController=new BallScaleIndicator(); + break; + case LineScale: + mIndicatorController=new LineScaleIndicator(); + break; + case LineScaleParty: + mIndicatorController=new LineScalePartyIndicator(); + break; + case BallScaleMultiple: + mIndicatorController=new BallScaleMultipleIndicator(); + break; + case BallPulseSync: + mIndicatorController=new BallPulseSyncIndicator(); + break; + case BallBeat: + mIndicatorController=new BallBeatIndicator(); + break; + case LineScalePulseOut: + mIndicatorController=new LineScalePulseOutIndicator(); + break; + case LineScalePulseOutRapid: + mIndicatorController=new LineScalePulseOutRapidIndicator(); + break; + case BallScaleRipple: + mIndicatorController=new BallScaleRippleIndicator(); + break; + case BallScaleRippleMultiple: + mIndicatorController=new BallScaleRippleMultipleIndicator(); + break; + case BallSpinFadeLoader: + mIndicatorController=new BallSpinFadeLoaderIndicator(); + break; + case LineSpinFadeLoader: + mIndicatorController=new LineSpinFadeLoaderIndicator(); + break; + case TriangleSkewSpin: + mIndicatorController=new TriangleSkewSpinIndicator(); + break; + case Pacman: + mIndicatorController=new PacmanIndicator(); + break; + case BallGridBeat: + mIndicatorController=new BallGridBeatIndicator(); + break; + case SemiCircleSpin: + mIndicatorController=new SemiCircleSpinIndicator(); + break; + } + mIndicatorController.setTarget(this); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int width = measureDimension(dp2px(DEFAULT_SIZE), widthMeasureSpec); + int height = measureDimension(dp2px(DEFAULT_SIZE), heightMeasureSpec); + setMeasuredDimension(width, height); + } + + private int measureDimension(int defaultSize,int measureSpec){ + int result = defaultSize; + int specMode = MeasureSpec.getMode(measureSpec); + int specSize = MeasureSpec.getSize(measureSpec); + if (specMode == MeasureSpec.EXACTLY) { + result = specSize; + } else if (specMode == MeasureSpec.AT_MOST) { + result = Math.min(defaultSize, specSize); + } else { + result = defaultSize; + } + return result; + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + drawIndicator(canvas); + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + super.onLayout(changed, left, top, right, bottom); + if (!mHasAnimation){ + mHasAnimation=true; + applyAnimation(); + } + } + + @Override + public void setVisibility(int v) { + if (getVisibility() != v) { + super.setVisibility(v); + if (v == GONE || v == INVISIBLE) { + mIndicatorController.setAnimationStatus(BaseIndicatorController.AnimStatus.END); + } else { + mIndicatorController.setAnimationStatus(BaseIndicatorController.AnimStatus.START); + } + } + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + mIndicatorController.setAnimationStatus(BaseIndicatorController.AnimStatus.CANCEL); + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + mIndicatorController.setAnimationStatus(BaseIndicatorController.AnimStatus.START); + } + + void drawIndicator(Canvas canvas){ + mIndicatorController.draw(canvas, mPaint); + } + + void applyAnimation(){ + mIndicatorController.initAnimation(); + } + + private int dp2px(int dpValue) { + return (int) getContext().getResources().getDisplayMetrics().density * dpValue; + } + + +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallBeatIndicator.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallBeatIndicator.java new file mode 100644 index 00000000..c636226a --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallBeatIndicator.java @@ -0,0 +1,82 @@ +package com.rmondjone.xrecyclerview.progressindicator.indicator; + +import android.animation.Animator; +import android.animation.ValueAnimator; +import android.graphics.Canvas; +import android.graphics.Paint; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Jack on 2015/10/19. + */ +public class BallBeatIndicator extends com.rmondjone.xrecyclerview.progressindicator.indicator.BaseIndicatorController { + + public static final float SCALE=1.0f; + + public static final int ALPHA=255; + + private float[] scaleFloats=new float[]{SCALE, + SCALE, + SCALE}; + + int[] alphas=new int[]{ALPHA, + ALPHA, + ALPHA,}; + + @Override + public void draw(Canvas canvas, Paint paint) { + float circleSpacing=4; + float radius=(getWidth()-circleSpacing*2)/6; + float x = getWidth()/ 2-(radius*2+circleSpacing); + float y=getHeight() / 2; + for (int i = 0; i < 3; i++) { + canvas.save(); + float translateX=x+(radius*2)*i+circleSpacing*i; + canvas.translate(translateX, y); + canvas.scale(scaleFloats[i], scaleFloats[i]); + paint.setAlpha(alphas[i]); + canvas.drawCircle(0, 0, radius, paint); + canvas.restore(); + } + } + + @Override + public List createAnimation() { + List animators=new ArrayList<>(); + int[] delays=new int[]{350,0,350}; + for (int i = 0; i < 3; i++) { + final int index=i; + ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.75f,1); + scaleAnim.setDuration(700); + scaleAnim.setRepeatCount(-1); + scaleAnim.setStartDelay(delays[i]); + scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + scaleFloats[index] = (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + scaleAnim.start(); + + ValueAnimator alphaAnim=ValueAnimator.ofInt(255,51,255); + alphaAnim.setDuration(700); + alphaAnim.setRepeatCount(-1); + alphaAnim.setStartDelay(delays[i]); + alphaAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + alphas[index] = (int) animation.getAnimatedValue(); + postInvalidate(); + } + }); + alphaAnim.start(); + animators.add(scaleAnim); + animators.add(alphaAnim); + } + return animators; + } + +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallClipRotateIndicator.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallClipRotateIndicator.java new file mode 100644 index 00000000..a932a546 --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallClipRotateIndicator.java @@ -0,0 +1,65 @@ +package com.rmondjone.xrecyclerview.progressindicator.indicator; + +import android.animation.Animator; +import android.animation.ValueAnimator; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.RectF; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Jack on 2015/10/16. + */ +public class BallClipRotateIndicator extends BaseIndicatorController { + + float scaleFloat=1,degrees; + + @Override + public void draw(Canvas canvas, Paint paint) { + paint.setStyle(Paint.Style.STROKE); + paint.setStrokeWidth(3); + + float circleSpacing=12; + float x = (getWidth()) / 2; + float y=(getHeight()) / 2; + canvas.translate(x, y); + canvas.scale(scaleFloat, scaleFloat); + canvas.rotate(degrees); + RectF rectF=new RectF(-x+circleSpacing,-y+circleSpacing,0+x-circleSpacing,0+y-circleSpacing); + canvas.drawArc(rectF, -45, 270, false, paint); + } + + @Override + public List createAnimation() { + List animators=new ArrayList<>(); + ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.6f,0.5f,1); + scaleAnim.setDuration(750); + scaleAnim.setRepeatCount(-1); + scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + scaleFloat = (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + scaleAnim.start(); + + ValueAnimator rotateAnim=ValueAnimator.ofFloat(0,180,360); + rotateAnim.setDuration(750); + rotateAnim.setRepeatCount(-1); + rotateAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + degrees = (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + rotateAnim.start(); + animators.add(scaleAnim); + animators.add(rotateAnim); + return animators; + } + +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallClipRotateMultipleIndicator.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallClipRotateMultipleIndicator.java new file mode 100644 index 00000000..90f82fd3 --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallClipRotateMultipleIndicator.java @@ -0,0 +1,85 @@ +package com.rmondjone.xrecyclerview.progressindicator.indicator; + +import android.animation.Animator; +import android.animation.ValueAnimator; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.RectF; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Jack on 2015/10/17. + */ +public class BallClipRotateMultipleIndicator extends BaseIndicatorController{ + + float scaleFloat=1,degrees; + + + @Override + public void draw(Canvas canvas, Paint paint) { + paint.setStrokeWidth(3); + paint.setStyle(Paint.Style.STROKE); + + float circleSpacing=12; + float x=getWidth()/2; + float y=getHeight()/2; + + canvas.save(); + + canvas.translate(x, y); + canvas.scale(scaleFloat, scaleFloat); + canvas.rotate(degrees); + + //draw two big arc + float[] bStartAngles=new float[]{135,-45}; + for (int i = 0; i < 2; i++) { + RectF rectF=new RectF(-x+circleSpacing,-y+circleSpacing,x-circleSpacing,y-circleSpacing); + canvas.drawArc(rectF, bStartAngles[i], 90, false, paint); + } + + canvas.restore(); + canvas.translate(x, y); + canvas.scale(scaleFloat, scaleFloat); + canvas.rotate(-degrees); + //draw two small arc + float[] sStartAngles=new float[]{225,45}; + for (int i = 0; i < 2; i++) { + RectF rectF=new RectF(-x/1.8f+circleSpacing,-y/1.8f+circleSpacing,x/1.8f-circleSpacing,y/1.8f-circleSpacing); + canvas.drawArc(rectF, sStartAngles[i], 90, false, paint); + } + } + + @Override + public List createAnimation() { + List animators=new ArrayList<>(); + ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.6f,1); + scaleAnim.setDuration(1000); + scaleAnim.setRepeatCount(-1); + scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + scaleFloat = (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + scaleAnim.start(); + + ValueAnimator rotateAnim=ValueAnimator.ofFloat(0, 180,360); + rotateAnim.setDuration(1000); + rotateAnim.setRepeatCount(-1); + rotateAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + degrees = (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + rotateAnim.start(); + animators.add(scaleAnim); + animators.add(rotateAnim); + return animators; + } + +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallClipRotatePulseIndicator.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallClipRotatePulseIndicator.java new file mode 100644 index 00000000..0e809948 --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallClipRotatePulseIndicator.java @@ -0,0 +1,94 @@ +package com.rmondjone.xrecyclerview.progressindicator.indicator; + +import android.animation.Animator; +import android.animation.ValueAnimator; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.RectF; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Jack on 2015/10/16. + */ +public class BallClipRotatePulseIndicator extends BaseIndicatorController { + + float scaleFloat1,scaleFloat2,degrees; + + + @Override + public void draw(Canvas canvas, Paint paint) { + float circleSpacing=12; + float x=getWidth()/2; + float y=getHeight()/2; + + //draw fill circle + canvas.save(); + canvas.translate(x, y); + canvas.scale(scaleFloat1, scaleFloat1); + paint.setStyle(Paint.Style.FILL); + canvas.drawCircle(0, 0, x / 2.5f, paint); + + canvas.restore(); + + canvas.translate(x, y); + canvas.scale(scaleFloat2, scaleFloat2); + canvas.rotate(degrees); + + paint.setStrokeWidth(3); + paint.setStyle(Paint.Style.STROKE); + + //draw two arc + float[] startAngles=new float[]{225,45}; + for (int i = 0; i < 2; i++) { + RectF rectF=new RectF(-x+circleSpacing,-y+circleSpacing,x-circleSpacing,y-circleSpacing); + canvas.drawArc(rectF, startAngles[i], 90, false, paint); + } + } + + @Override + public List createAnimation() { + ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.3f,1); + scaleAnim.setDuration(1000); + scaleAnim.setRepeatCount(-1); + scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + scaleFloat1 = (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + scaleAnim.start(); + + ValueAnimator scaleAnim2=ValueAnimator.ofFloat(1,0.6f,1); + scaleAnim2.setDuration(1000); + scaleAnim2.setRepeatCount(-1); + scaleAnim2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + scaleFloat2 = (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + scaleAnim2.start(); + + ValueAnimator rotateAnim=ValueAnimator.ofFloat(0, 180,360); + rotateAnim.setDuration(1000); + rotateAnim.setRepeatCount(-1); + rotateAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + degrees = (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + rotateAnim.start(); + List animators=new ArrayList<>(); + animators.add(scaleAnim); + animators.add(scaleAnim2); + animators.add(rotateAnim); + return animators; + } + +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallGridBeatIndicator.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallGridBeatIndicator.java new file mode 100644 index 00000000..107932ca --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallGridBeatIndicator.java @@ -0,0 +1,76 @@ +package com.rmondjone.xrecyclerview.progressindicator.indicator; + +import android.animation.Animator; +import android.animation.ValueAnimator; +import android.graphics.Canvas; +import android.graphics.Paint; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Jack on 2015/10/20. + */ +public class BallGridBeatIndicator extends BaseIndicatorController { + + public static final int ALPHA=255; + + int[] alphas=new int[]{ALPHA, + ALPHA, + ALPHA, + ALPHA, + ALPHA, + ALPHA, + ALPHA, + ALPHA, + ALPHA}; + + @Override + public void draw(Canvas canvas, Paint paint) { + float circleSpacing=4; + float radius=(getWidth()-circleSpacing*4)/6; + float x = getWidth()/ 2-(radius*2+circleSpacing); + float y = getWidth()/ 2-(radius*2+circleSpacing); + + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + canvas.save(); + float translateX=x+(radius*2)*j+circleSpacing*j; + float translateY=y+(radius*2)*i+circleSpacing*i; + canvas.translate(translateX, translateY); + paint.setAlpha(alphas[3 * i + j]); + canvas.drawCircle(0, 0, radius, paint); + canvas.restore(); + } + } + } + + @Override + public List createAnimation() { + List animators=new ArrayList<>(); + + int[] durations={960, 930, 1190, 1130, 1340, 940, 1200, 820, 1190}; + int[] delays= {360, 400, 680, 410, 710, -150, -120, 10, 320}; + + for (int i = 0; i < 9; i++) { + final int index=i; + ValueAnimator alphaAnim=ValueAnimator.ofInt(255, 168,255); + alphaAnim.setDuration(durations[i]); + alphaAnim.setRepeatCount(-1); + alphaAnim.setStartDelay(delays[i]); + alphaAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + alphas[index] = (int) animation.getAnimatedValue(); + postInvalidate(); + } + }); + alphaAnim.start(); + animators.add(alphaAnim); + } + return animators; + } + + + +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallGridPulseIndicator.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallGridPulseIndicator.java new file mode 100644 index 00000000..fdbfdfed --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallGridPulseIndicator.java @@ -0,0 +1,103 @@ +package com.rmondjone.xrecyclerview.progressindicator.indicator; + +import android.animation.Animator; +import android.animation.ValueAnimator; +import android.graphics.Canvas; +import android.graphics.Paint; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Jack on 2015/10/16. + */ +public class BallGridPulseIndicator extends BaseIndicatorController{ + + public static final int ALPHA=255; + + public static final float SCALE=1.0f; + + int[] alphas=new int[]{ALPHA, + ALPHA, + ALPHA, + ALPHA, + ALPHA, + ALPHA, + ALPHA, + ALPHA, + ALPHA}; + + float[] scaleFloats=new float[]{SCALE, + SCALE, + SCALE, + SCALE, + SCALE, + SCALE, + SCALE, + SCALE, + SCALE}; + + + + @Override + public void draw(Canvas canvas, Paint paint) { + float circleSpacing=4; + float radius=(getWidth()-circleSpacing*4)/6; + float x = getWidth()/ 2-(radius*2+circleSpacing); + float y = getWidth()/ 2-(radius*2+circleSpacing); + + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + canvas.save(); + float translateX=x+(radius*2)*j+circleSpacing*j; + float translateY=y+(radius*2)*i+circleSpacing*i; + canvas.translate(translateX, translateY); + canvas.scale(scaleFloats[3 * i + j], scaleFloats[3 * i + j]); + paint.setAlpha(alphas[3 * i + j]); + canvas.drawCircle(0, 0, radius, paint); + canvas.restore(); + } + } + } + + @Override + public List createAnimation() { + List animators=new ArrayList<>(); + int[] durations={720, 1020, 1280, 1420, 1450, 1180, 870, 1450, 1060}; + int[] delays= {-60, 250, -170, 480, 310, 30, 460, 780, 450}; + + for (int i = 0; i < 9; i++) { + final int index=i; + ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.5f,1); + scaleAnim.setDuration(durations[i]); + scaleAnim.setRepeatCount(-1); + scaleAnim.setStartDelay(delays[i]); + scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + scaleFloats[index] = (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + scaleAnim.start(); + + ValueAnimator alphaAnim=ValueAnimator.ofInt(255, 210, 122, 255); + alphaAnim.setDuration(durations[i]); + alphaAnim.setRepeatCount(-1); + alphaAnim.setStartDelay(delays[i]); + alphaAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + alphas[index] = (int) animation.getAnimatedValue(); + postInvalidate(); + } + }); + alphaAnim.start(); + animators.add(scaleAnim); + animators.add(alphaAnim); + } + return animators; + } + + +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallPulseIndicator.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallPulseIndicator.java new file mode 100644 index 00000000..79616a49 --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallPulseIndicator.java @@ -0,0 +1,68 @@ +package com.rmondjone.xrecyclerview.progressindicator.indicator; + +import android.animation.Animator; +import android.animation.ValueAnimator; +import android.graphics.Canvas; +import android.graphics.Paint; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Jack on 2015/10/16. + */ +public class BallPulseIndicator extends BaseIndicatorController{ + + public static final float SCALE=1.0f; + + //scale x ,y + private float[] scaleFloats=new float[]{SCALE, + SCALE, + SCALE}; + + + + @Override + public void draw(Canvas canvas, Paint paint) { + float circleSpacing=4; + float radius=(Math.min(getWidth(),getHeight())-circleSpacing*2)/6; + float x = getWidth()/ 2-(radius*2+circleSpacing); + float y=getHeight() / 2; + for (int i = 0; i < 3; i++) { + canvas.save(); + float translateX=x+(radius*2)*i+circleSpacing*i; + canvas.translate(translateX, y); + canvas.scale(scaleFloats[i], scaleFloats[i]); + canvas.drawCircle(0, 0, radius, paint); + canvas.restore(); + } + } + + @Override + public List createAnimation() { + List animators=new ArrayList<>(); + int[] delays=new int[]{120,240,360}; + for (int i = 0; i < 3; i++) { + final int index=i; + + ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.3f,1); + + scaleAnim.setDuration(750); + scaleAnim.setRepeatCount(-1); + scaleAnim.setStartDelay(delays[i]); + + scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + scaleFloats[index] = (float) animation.getAnimatedValue(); + postInvalidate(); + + } + }); + scaleAnim.start(); + animators.add(scaleAnim); + } + return animators; + } + +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallPulseRiseIndicator.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallPulseRiseIndicator.java new file mode 100644 index 00000000..5fe01b6f --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallPulseRiseIndicator.java @@ -0,0 +1,41 @@ +package com.rmondjone.xrecyclerview.progressindicator.indicator; + +import android.animation.Animator; +import android.animation.ObjectAnimator; +import android.animation.PropertyValuesHolder; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.view.animation.LinearInterpolator; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Jack on 2015/10/17. + */ +public class BallPulseRiseIndicator extends BaseIndicatorController{ + + @Override + public void draw(Canvas canvas, Paint paint) { + float radius=getWidth()/10; + canvas.drawCircle(getWidth()/4,radius*2,radius,paint); + canvas.drawCircle(getWidth()*3/4,radius*2,radius,paint); + + canvas.drawCircle(radius,getHeight()-2*radius,radius,paint); + canvas.drawCircle(getWidth()/2,getHeight()-2*radius,radius,paint); + canvas.drawCircle(getWidth()-radius,getHeight()-2*radius,radius,paint); + } + + @Override + public List createAnimation() { + PropertyValuesHolder rotation6=PropertyValuesHolder.ofFloat("rotationX",0,360); + ObjectAnimator animator=ObjectAnimator.ofPropertyValuesHolder(getTarget(), rotation6); + animator.setInterpolator(new LinearInterpolator()); + animator.setRepeatCount(-1); + animator.setDuration(1500); + animator.start(); + List animators=new ArrayList<>(); + animators.add(animator); + return animators; + } +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallPulseSyncIndicator.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallPulseSyncIndicator.java new file mode 100644 index 00000000..cf1db954 --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallPulseSyncIndicator.java @@ -0,0 +1,57 @@ +package com.rmondjone.xrecyclerview.progressindicator.indicator; + +import android.animation.Animator; +import android.animation.ValueAnimator; +import android.graphics.Canvas; +import android.graphics.Paint; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Jack on 2015/10/19. + */ +public class BallPulseSyncIndicator extends BaseIndicatorController { + + float[] translateYFloats=new float[3]; + + @Override + public void draw(Canvas canvas, Paint paint) { + float circleSpacing=4; + float radius=(getWidth()-circleSpacing*2)/6; + float x = getWidth()/ 2-(radius*2+circleSpacing); + for (int i = 0; i < 3; i++) { + canvas.save(); + float translateX=x+(radius*2)*i+circleSpacing*i; + canvas.translate(translateX, translateYFloats[i]); + canvas.drawCircle(0, 0, radius, paint); + canvas.restore(); + } + } + + @Override + public List createAnimation() { + List animators=new ArrayList<>(); + float circleSpacing=4; + float radius=(getWidth()-circleSpacing*2)/6; + int[] delays=new int[]{70,140,210}; + for (int i = 0; i < 3; i++) { + final int index=i; + ValueAnimator scaleAnim=ValueAnimator.ofFloat(getHeight()/2,getHeight()/2-radius*2,getHeight()/2); + scaleAnim.setDuration(600); + scaleAnim.setRepeatCount(-1); + scaleAnim.setStartDelay(delays[i]); + scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + translateYFloats[index] = (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + scaleAnim.start(); + animators.add(scaleAnim); + } + return animators; + } + +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallRotateIndicator.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallRotateIndicator.java new file mode 100644 index 00000000..f3ac1aa9 --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallRotateIndicator.java @@ -0,0 +1,71 @@ +package com.rmondjone.xrecyclerview.progressindicator.indicator; + +import android.animation.Animator; +import android.animation.ObjectAnimator; +import android.animation.ValueAnimator; +import android.graphics.Canvas; +import android.graphics.Paint; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Jack on 2015/10/17. + */ +public class BallRotateIndicator extends BaseIndicatorController{ + + float scaleFloat=0.5f; + + + @Override + public void draw(Canvas canvas, Paint paint) { + float radius=getWidth()/10; + float x = getWidth()/ 2; + float y=getHeight()/2; + + canvas.save(); + canvas.translate(x - radius * 2 - radius, y); + canvas.scale(scaleFloat, scaleFloat); + canvas.drawCircle(0, 0, radius, paint); + canvas.restore(); + + canvas.save(); + canvas.translate(x, y); + canvas.scale(scaleFloat, scaleFloat); + canvas.drawCircle(0, 0, radius, paint); + canvas.restore(); + + canvas.save(); + canvas.translate(x + radius * 2 + radius, y); + canvas.scale(scaleFloat, scaleFloat); + canvas.drawCircle(0,0,radius, paint); + canvas.restore(); + } + + @Override + public List createAnimation() { + List animators=new ArrayList<>(); + ValueAnimator scaleAnim=ValueAnimator.ofFloat(0.5f,1,0.5f); + scaleAnim.setDuration(1000); + scaleAnim.setRepeatCount(-1); + scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + scaleFloat = (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + scaleAnim.start(); + + ObjectAnimator rotateAnim=ObjectAnimator.ofFloat(getTarget(),"rotation",0,180,360); + rotateAnim.setDuration(1000); + rotateAnim.setRepeatCount(-1); + rotateAnim.start(); + + animators.add(scaleAnim); + animators.add(rotateAnim); + return animators; + } + + +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallScaleIndicator.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallScaleIndicator.java new file mode 100644 index 00000000..95141775 --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallScaleIndicator.java @@ -0,0 +1,63 @@ +package com.rmondjone.xrecyclerview.progressindicator.indicator; + +import android.animation.Animator; +import android.animation.ValueAnimator; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.view.animation.LinearInterpolator; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Jack on 2015/10/19. + */ +public class BallScaleIndicator extends BaseIndicatorController { + + float scale=1; + int alpha=255; + + @Override + public void draw(Canvas canvas, Paint paint) { + float circleSpacing=4; + paint.setAlpha(alpha); + canvas.scale(scale,scale,getWidth()/2,getHeight()/2); + paint.setAlpha(alpha); + canvas.drawCircle(getWidth()/2,getHeight()/2,getWidth()/2-circleSpacing,paint); + } + + @Override + public List createAnimation() { + List animators=new ArrayList<>(); + ValueAnimator scaleAnim=ValueAnimator.ofFloat(0,1); + scaleAnim.setInterpolator(new LinearInterpolator()); + scaleAnim.setDuration(1000); + scaleAnim.setRepeatCount(-1); + scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + scale = (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + scaleAnim.start(); + + ValueAnimator alphaAnim=ValueAnimator.ofInt(255, 0); + alphaAnim.setInterpolator(new LinearInterpolator()); + alphaAnim.setDuration(1000); + alphaAnim.setRepeatCount(-1); + alphaAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + alpha = (int) animation.getAnimatedValue(); + postInvalidate(); + } + }); + alphaAnim.start(); + animators.add(scaleAnim); + animators.add(alphaAnim); + return animators; + } + + +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallScaleMultipleIndicator.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallScaleMultipleIndicator.java new file mode 100644 index 00000000..507db9bd --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallScaleMultipleIndicator.java @@ -0,0 +1,70 @@ +package com.rmondjone.xrecyclerview.progressindicator.indicator; + +import android.animation.Animator; +import android.animation.ValueAnimator; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.view.animation.LinearInterpolator; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Jack on 2015/10/19. + */ +public class BallScaleMultipleIndicator extends BaseIndicatorController { + + float[] scaleFloats=new float[]{1,1,1}; + int[] alphaInts=new int[]{255,255,255}; + + @Override + public void draw(Canvas canvas, Paint paint) { + float circleSpacing=4; + for (int i = 0; i < 3; i++) { + paint.setAlpha(alphaInts[i]); + canvas.scale(scaleFloats[i],scaleFloats[i],getWidth()/2,getHeight()/2); + canvas.drawCircle(getWidth()/2,getHeight()/2,getWidth()/2-circleSpacing,paint); + } + } + + @Override + public List createAnimation() { + List animators=new ArrayList<>(); + long[] delays=new long[]{0, 200, 400}; + for (int i = 0; i < 3; i++) { + final int index=i; + ValueAnimator scaleAnim=ValueAnimator.ofFloat(0,1); + scaleAnim.setInterpolator(new LinearInterpolator()); + scaleAnim.setDuration(1000); + scaleAnim.setRepeatCount(-1); + scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + scaleFloats[index] = (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + scaleAnim.setStartDelay(delays[i]); + scaleAnim.start(); + + ValueAnimator alphaAnim=ValueAnimator.ofInt(255,0); + alphaAnim.setInterpolator(new LinearInterpolator()); + alphaAnim.setDuration(1000); + alphaAnim.setRepeatCount(-1); + alphaAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + alphaInts[index] = (int) animation.getAnimatedValue(); + postInvalidate(); + } + }); + scaleAnim.setStartDelay(delays[i]); + alphaAnim.start(); + + animators.add(scaleAnim); + animators.add(alphaAnim); + } + return animators; + } + +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallScaleRippleIndicator.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallScaleRippleIndicator.java new file mode 100644 index 00000000..5adb4be1 --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallScaleRippleIndicator.java @@ -0,0 +1,59 @@ +package com.rmondjone.xrecyclerview.progressindicator.indicator; + +import android.animation.Animator; +import android.animation.ValueAnimator; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.view.animation.LinearInterpolator; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Jack on 2015/10/19. + */ +public class BallScaleRippleIndicator extends BallScaleIndicator { + + + @Override + public void draw(Canvas canvas, Paint paint) { + paint.setStyle(Paint.Style.STROKE); + paint.setStrokeWidth(3); + super.draw(canvas, paint); + } + + @Override + public List createAnimation() { + List animators=new ArrayList<>(); + ValueAnimator scaleAnim=ValueAnimator.ofFloat(0,1); + scaleAnim.setInterpolator(new LinearInterpolator()); + scaleAnim.setDuration(1000); + scaleAnim.setRepeatCount(-1); + scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + scale = (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + scaleAnim.start(); + + ValueAnimator alphaAnim=ValueAnimator.ofInt(0, 255); + alphaAnim.setInterpolator(new LinearInterpolator()); + alphaAnim.setDuration(1000); + alphaAnim.setRepeatCount(-1); + alphaAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + alpha = (int) animation.getAnimatedValue(); + postInvalidate(); + } + }); + alphaAnim.start(); + + animators.add(scaleAnim); + animators.add(alphaAnim); + return animators; + } + +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallScaleRippleMultipleIndicator.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallScaleRippleMultipleIndicator.java new file mode 100644 index 00000000..5b81cedf --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallScaleRippleMultipleIndicator.java @@ -0,0 +1,65 @@ +package com.rmondjone.xrecyclerview.progressindicator.indicator; + +import android.animation.Animator; +import android.animation.ValueAnimator; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.view.animation.LinearInterpolator; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Jack on 2015/10/19. + */ +public class BallScaleRippleMultipleIndicator extends BallScaleMultipleIndicator{ + + + @Override + public void draw(Canvas canvas, Paint paint) { + paint.setStyle(Paint.Style.STROKE); + paint.setStrokeWidth(3); + super.draw(canvas, paint); + } + + @Override + public List createAnimation() { + List animators=new ArrayList<>(); + long[] delays=new long[]{0, 200, 400}; + for (int i = 0; i < 3; i++) { + final int index=i; + ValueAnimator scaleAnim=ValueAnimator.ofFloat(0,1); + scaleAnim.setInterpolator(new LinearInterpolator()); + scaleAnim.setDuration(1000); + scaleAnim.setRepeatCount(-1); + scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + scaleFloats[index] = (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + scaleAnim.setStartDelay(delays[i]); + scaleAnim.start(); + + ValueAnimator alphaAnim=ValueAnimator.ofInt(0,255); + scaleAnim.setInterpolator(new LinearInterpolator()); + alphaAnim.setDuration(1000); + alphaAnim.setRepeatCount(-1); + alphaAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + alphaInts[index] = (int) animation.getAnimatedValue(); + postInvalidate(); + } + }); + scaleAnim.setStartDelay(delays[i]); + alphaAnim.start(); + + animators.add(scaleAnim); + animators.add(alphaAnim); + } + return animators; + } + +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallSpinFadeLoaderIndicator.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallSpinFadeLoaderIndicator.java new file mode 100644 index 00000000..859b54f9 --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallSpinFadeLoaderIndicator.java @@ -0,0 +1,116 @@ +package com.rmondjone.xrecyclerview.progressindicator.indicator; + +import android.animation.Animator; +import android.animation.ValueAnimator; +import android.graphics.Canvas; +import android.graphics.Paint; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Jack on 2015/10/20. + */ +public class BallSpinFadeLoaderIndicator extends BaseIndicatorController { + + public static final float SCALE=1.0f; + + public static final int ALPHA=255; + + float[] scaleFloats=new float[]{SCALE, + SCALE, + SCALE, + SCALE, + SCALE, + SCALE, + SCALE, + SCALE}; + + int[] alphas=new int[]{ALPHA, + ALPHA, + ALPHA, + ALPHA, + ALPHA, + ALPHA, + ALPHA, + ALPHA}; + + + @Override + public void draw(Canvas canvas, Paint paint) { + float radius=getWidth()/10; + for (int i = 0; i < 8; i++) { + canvas.save(); + Point point=circleAt(getWidth(),getHeight(),getWidth()/2-radius,i*(Math.PI/4)); + canvas.translate(point.x,point.y); + canvas.scale(scaleFloats[i],scaleFloats[i]); + paint.setAlpha(alphas[i]); + canvas.drawCircle(0,0,radius,paint); + canvas.restore(); + } + } + + /** + * 圆O的圆心为(a,b),半径为R,点A与到X轴的为角α. + *则点A的坐标为(a+R*cosα,b+R*sinα) + * @param width + * @param height + * @param radius + * @param angle + * @return + */ + Point circleAt(int width,int height,float radius,double angle){ + float x= (float) (width/2+radius*(Math.cos(angle))); + float y= (float) (height/2+radius*(Math.sin(angle))); + return new Point(x,y); + } + + @Override + public List createAnimation() { + List animators=new ArrayList<>(); + int[] delays= {0, 120, 240, 360, 480, 600, 720, 780, 840}; + for (int i = 0; i < 8; i++) { + final int index=i; + ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.4f,1); + scaleAnim.setDuration(1000); + scaleAnim.setRepeatCount(-1); + scaleAnim.setStartDelay(delays[i]); + scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + scaleFloats[index] = (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + scaleAnim.start(); + + ValueAnimator alphaAnim=ValueAnimator.ofInt(255, 77, 255); + alphaAnim.setDuration(1000); + alphaAnim.setRepeatCount(-1); + alphaAnim.setStartDelay(delays[i]); + alphaAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + alphas[index] = (int) animation.getAnimatedValue(); + postInvalidate(); + } + }); + alphaAnim.start(); + animators.add(scaleAnim); + animators.add(alphaAnim); + } + return animators; + } + + final class Point{ + public float x; + public float y; + + public Point(float x, float y){ + this.x=x; + this.y=y; + } + } + + +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallTrianglePathIndicator.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallTrianglePathIndicator.java new file mode 100644 index 00000000..8eca225d --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallTrianglePathIndicator.java @@ -0,0 +1,82 @@ +package com.rmondjone.xrecyclerview.progressindicator.indicator; + +import android.animation.Animator; +import android.animation.ValueAnimator; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.view.animation.LinearInterpolator; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Jack on 2015/10/19. + */ +public class BallTrianglePathIndicator extends BaseIndicatorController { + + float[] translateX=new float[3],translateY=new float[3]; + + @Override + public void draw(Canvas canvas, Paint paint) { + paint.setStrokeWidth(3); + paint.setStyle(Paint.Style.STROKE); + for (int i = 0; i < 3; i++) { + canvas.save(); + canvas.translate(translateX[i], translateY[i]); + canvas.drawCircle(0, 0, getWidth() / 10, paint); + canvas.restore(); + } + } + + @Override + public List createAnimation() { + List animators=new ArrayList<>(); + float startX=getWidth()/5; + float startY=getWidth()/5; + for (int i = 0; i < 3; i++) { + final int index=i; + ValueAnimator translateXAnim=ValueAnimator.ofFloat(getWidth()/2,getWidth()-startX,startX,getWidth()/2); + if (i==1){ + translateXAnim=ValueAnimator.ofFloat(getWidth()-startX,startX,getWidth()/2,getWidth()-startX); + }else if (i==2){ + translateXAnim=ValueAnimator.ofFloat(startX,getWidth()/2,getWidth()-startX,startX); + } + ValueAnimator translateYAnim=ValueAnimator.ofFloat(startY,getHeight()-startY,getHeight()-startY,startY); + if (i==1){ + translateYAnim=ValueAnimator.ofFloat(getHeight()-startY,getHeight()-startY,startY,getHeight()-startY); + }else if (i==2){ + translateYAnim=ValueAnimator.ofFloat(getHeight()-startY,startY,getHeight()-startY,getHeight()-startY); + } + + translateXAnim.setDuration(2000); + translateXAnim.setInterpolator(new LinearInterpolator()); + translateXAnim.setRepeatCount(-1); + translateXAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + translateX [index]= (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + translateXAnim.start(); + + translateYAnim.setDuration(2000); + translateYAnim.setInterpolator(new LinearInterpolator()); + translateYAnim.setRepeatCount(-1); + translateYAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + translateY [index]= (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + translateYAnim.start(); + + animators.add(translateXAnim); + animators.add(translateYAnim); + } + return animators; + } + + +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallZigZagDeflectIndicator.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallZigZagDeflectIndicator.java new file mode 100644 index 00000000..398eefba --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallZigZagDeflectIndicator.java @@ -0,0 +1,64 @@ +package com.rmondjone.xrecyclerview.progressindicator.indicator; + + +import android.animation.Animator; +import android.animation.ValueAnimator; +import android.view.animation.LinearInterpolator; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Jack on 2015/10/19. + */ +public class BallZigZagDeflectIndicator extends BallZigZagIndicator { + + + + + @Override + public List createAnimation() { + List animators=new ArrayList<>(); + float startX=getWidth()/6; + float startY=getWidth()/6; + for (int i = 0; i < 2; i++) { + final int index=i; + ValueAnimator translateXAnim=ValueAnimator.ofFloat(startX,getWidth()-startX,startX,getWidth()-startX,startX); + if (i==1){ + translateXAnim=ValueAnimator.ofFloat(getWidth()-startX,startX,getWidth()-startX,startX,getWidth()-startX); + } + ValueAnimator translateYAnim=ValueAnimator.ofFloat(startY,startY,getHeight()-startY,getHeight()-startY,startY); + if (i==1){ + translateYAnim=ValueAnimator.ofFloat(getHeight()-startY,getHeight()-startY,startY,startY,getHeight()-startY); + } + + translateXAnim.setDuration(2000); + translateXAnim.setInterpolator(new LinearInterpolator()); + translateXAnim.setRepeatCount(-1); + translateXAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + translateX [index]= (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + translateXAnim.start(); + + translateYAnim.setDuration(2000); + translateYAnim.setInterpolator(new LinearInterpolator()); + translateYAnim.setRepeatCount(-1); + translateYAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + translateY [index]= (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + translateYAnim.start(); + + animators.add(translateXAnim); + animators.add(translateYAnim); + } + return animators; + } + +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallZigZagIndicator.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallZigZagIndicator.java new file mode 100644 index 00000000..252aed05 --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BallZigZagIndicator.java @@ -0,0 +1,75 @@ +package com.rmondjone.xrecyclerview.progressindicator.indicator; + +import android.animation.Animator; +import android.animation.ValueAnimator; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.view.animation.LinearInterpolator; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Jack on 2015/10/19. + */ +public class BallZigZagIndicator extends BaseIndicatorController { + + float[] translateX=new float[2],translateY=new float[2]; + + + @Override + public void draw(Canvas canvas, Paint paint) { + for (int i = 0; i < 2; i++) { + canvas.save(); + canvas.translate(translateX[i], translateY[i]); + canvas.drawCircle(0, 0, getWidth() / 10, paint); + canvas.restore(); + } + } + + @Override + public List createAnimation() { + List animators=new ArrayList<>(); + float startX=getWidth()/6; + float startY=getWidth()/6; + for (int i = 0; i < 2; i++) { + final int index=i; + ValueAnimator translateXAnim=ValueAnimator.ofFloat(startX,getWidth()-startX,getWidth()/2,startX); + if (i==1){ + translateXAnim=ValueAnimator.ofFloat(getWidth()-startX,startX,getWidth()/2,getWidth()-startX); + } + ValueAnimator translateYAnim=ValueAnimator.ofFloat(startY,startY,getHeight()/2,startY); + if (i==1){ + translateYAnim=ValueAnimator.ofFloat(getHeight()-startY,getHeight()-startY,getHeight()/2,getHeight()-startY); + } + + translateXAnim.setDuration(1000); + translateXAnim.setInterpolator(new LinearInterpolator()); + translateXAnim.setRepeatCount(-1); + translateXAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + translateX[index] = (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + translateXAnim.start(); + + translateYAnim.setDuration(1000); + translateYAnim.setInterpolator(new LinearInterpolator()); + translateYAnim.setRepeatCount(-1); + translateYAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + translateY[index] = (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + translateYAnim.start(); + animators.add(translateXAnim); + animators.add(translateYAnim); + } + return animators; + } + +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BaseIndicatorController.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BaseIndicatorController.java new file mode 100644 index 00000000..4815b1dc --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/BaseIndicatorController.java @@ -0,0 +1,99 @@ +package com.rmondjone.xrecyclerview.progressindicator.indicator; + +import android.animation.Animator; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.view.View; +import java.util.List; + +/** + * Created by Jack on 2015/10/15. + */ +public abstract class BaseIndicatorController { + + + private View mTarget; + + private List mAnimators; + + + public void setTarget(View target){ + this.mTarget=target; + } + + public View getTarget(){ + return mTarget; + } + + + public int getWidth(){ + return mTarget.getWidth(); + } + + public int getHeight(){ + return mTarget.getHeight(); + } + + public void postInvalidate(){ + mTarget.postInvalidate(); + } + + /** + * draw indicator + * @param canvas + * @param paint + */ + public abstract void draw(Canvas canvas,Paint paint); + + /** + * create animation or animations + */ + public abstract List createAnimation(); + + public void initAnimation(){ + mAnimators=createAnimation(); + } + + /** + * make animation to start or end when target + * view was be Visible or Gone or Invisible. + * make animation to cancel when target view + * be onDetachedFromWindow. + * @param animStatus + */ + public void setAnimationStatus(AnimStatus animStatus){ + if (mAnimators==null){ + return; + } + int count=mAnimators.size(); + for (int i = 0; i < count; i++) { + Animator animator=mAnimators.get(i); + boolean isRunning=animator.isRunning(); + switch (animStatus){ + case START: + if (!isRunning){ + animator.start(); + } + break; + case END: + if (isRunning){ + animator.end(); + } + break; + case CANCEL: + if (isRunning){ + animator.cancel(); + } + break; + } + } + } + + + public enum AnimStatus{ + START,END,CANCEL + } + + + +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/CubeTransitionIndicator.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/CubeTransitionIndicator.java new file mode 100644 index 00000000..5b46d157 --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/CubeTransitionIndicator.java @@ -0,0 +1,110 @@ +package com.rmondjone.xrecyclerview.progressindicator.indicator; + +import android.animation.Animator; +import android.animation.ValueAnimator; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.RectF; +import android.view.animation.LinearInterpolator; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Jack on 2015/10/18. + */ +public class CubeTransitionIndicator extends BaseIndicatorController { + + float[] translateX=new float[2],translateY=new float[2]; + float degrees,scaleFloat=1.0f; + + @Override + public void draw(Canvas canvas, Paint paint) { + float rWidth=getWidth()/5; + float rHeight=getHeight()/5; + for (int i = 0; i < 2; i++) { + canvas.save(); + canvas.translate(translateX[i], translateY[i]); + canvas.rotate(degrees); + canvas.scale(scaleFloat,scaleFloat); + RectF rectF=new RectF(-rWidth/2,-rHeight/2,rWidth/2,rHeight/2); + canvas.drawRect(rectF,paint); + canvas.restore(); + } + } + + @Override + public List createAnimation() { + List animators=new ArrayList<>(); + float startX=getWidth()/5; + float startY=getHeight()/5; + for (int i = 0; i < 2; i++) { + final int index=i; + translateX[index]=startX; + ValueAnimator translationXAnim=ValueAnimator.ofFloat(startX,getWidth()-startX,getWidth()-startX, startX,startX); + if (i==1){ + translationXAnim=ValueAnimator.ofFloat(getWidth()-startX,startX,startX, getWidth()-startX,getWidth()-startX); + } + translationXAnim.setInterpolator(new LinearInterpolator()); + translationXAnim.setDuration(1600); + translationXAnim.setRepeatCount(-1); + translationXAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + translateX[index] = (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + translationXAnim.start(); + translateY[index]=startY; + ValueAnimator translationYAnim=ValueAnimator.ofFloat(startY,startY,getHeight()-startY,getHeight()- startY,startY); + if (i==1){ + translationYAnim=ValueAnimator.ofFloat(getHeight()-startY,getHeight()-startY,startY,startY,getHeight()-startY); + } + translationYAnim.setDuration(1600); + translationYAnim.setInterpolator(new LinearInterpolator()); + translationYAnim.setRepeatCount(-1); + translationYAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + translateY[index] = (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + translationYAnim.start(); + + animators.add(translationXAnim); + animators.add(translationYAnim); + } + + ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.5f,1,0.5f,1); + scaleAnim.setDuration(1600); + scaleAnim.setInterpolator(new LinearInterpolator()); + scaleAnim.setRepeatCount(-1); + scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + scaleFloat = (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + scaleAnim.start(); + + ValueAnimator rotateAnim=ValueAnimator.ofFloat(0,180,360,1.5f*360,2*360); + rotateAnim.setDuration(1600); + rotateAnim.setInterpolator(new LinearInterpolator()); + rotateAnim.setRepeatCount(-1); + rotateAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + degrees = (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + rotateAnim.start(); + + animators.add(scaleAnim); + animators.add(rotateAnim); + return animators; + } +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/LineScaleIndicator.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/LineScaleIndicator.java new file mode 100644 index 00000000..e502f2d9 --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/LineScaleIndicator.java @@ -0,0 +1,62 @@ +package com.rmondjone.xrecyclerview.progressindicator.indicator; + +import android.animation.Animator; +import android.animation.ValueAnimator; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.RectF; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Jack on 2015/10/19. + */ +public class LineScaleIndicator extends BaseIndicatorController { + + public static final float SCALE=1.0f; + + float[] scaleYFloats=new float[]{SCALE, + SCALE, + SCALE, + SCALE, + SCALE,}; + + @Override + public void draw(Canvas canvas, Paint paint) { + float translateX=getWidth()/11; + float translateY=getHeight()/2; + for (int i = 0; i < 5; i++) { + canvas.save(); + canvas.translate((2 + i * 2) * translateX - translateX / 2, translateY); + canvas.scale(SCALE, scaleYFloats[i]); + RectF rectF=new RectF(-translateX/2,-getHeight()/2.5f,translateX/2,getHeight()/2.5f); + canvas.drawRoundRect(rectF, 5, 5, paint); + canvas.restore(); + } + } + + @Override + public List createAnimation() { + List animators=new ArrayList<>(); + long[] delays=new long[]{100,200,300,400,500}; + for (int i = 0; i < 5; i++) { + final int index=i; + ValueAnimator scaleAnim=ValueAnimator.ofFloat(1, 0.4f, 1); + scaleAnim.setDuration(1000); + scaleAnim.setRepeatCount(-1); + scaleAnim.setStartDelay(delays[i]); + scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + scaleYFloats[index] = (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + scaleAnim.start(); + animators.add(scaleAnim); + } + return animators; + } + +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/LineScalePartyIndicator.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/LineScalePartyIndicator.java new file mode 100644 index 00000000..2b681f05 --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/LineScalePartyIndicator.java @@ -0,0 +1,64 @@ +package com.rmondjone.xrecyclerview.progressindicator.indicator; + +import android.animation.Animator; +import android.animation.ValueAnimator; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.RectF; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Jack on 2015/10/19. + */ +public class LineScalePartyIndicator extends BaseIndicatorController { + + public static final float SCALE=1.0f; + + float[] scaleFloats=new float[]{SCALE, + SCALE, + SCALE, + SCALE, + SCALE,}; + + @Override + public void draw(Canvas canvas, Paint paint) { + float translateX=getWidth()/9; + float translateY=getHeight()/2; + for (int i = 0; i < 4; i++) { + canvas.save(); + canvas.translate((2 + i * 2) * translateX - translateX / 2, translateY); + canvas.scale(scaleFloats[i], scaleFloats[i]); + RectF rectF=new RectF(-translateX/2,-getHeight()/2.5f,translateX/2,getHeight()/2.5f); + canvas.drawRoundRect(rectF,5,5,paint); + canvas.restore(); + } + } + + @Override + public List createAnimation() { + List animators=new ArrayList<>(); + long[] durations=new long[]{1260, 430, 1010, 730}; + long[] delays=new long[]{770, 290, 280, 740}; + for (int i = 0; i < 4; i++) { + final int index=i; + ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.4f,1); + scaleAnim.setDuration(durations[i]); + scaleAnim.setRepeatCount(-1); + scaleAnim.setStartDelay(delays[i]); + scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + scaleFloats[index] = (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + scaleAnim.start(); + animators.add(scaleAnim); + } + return animators; + } + + +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/LineScalePulseOutIndicator.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/LineScalePulseOutIndicator.java new file mode 100644 index 00000000..e3134cc7 --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/LineScalePulseOutIndicator.java @@ -0,0 +1,37 @@ +package com.rmondjone.xrecyclerview.progressindicator.indicator; + +import android.animation.Animator; +import android.animation.ValueAnimator; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Jack on 2015/10/19. + */ +public class LineScalePulseOutIndicator extends LineScaleIndicator { + + @Override + public List createAnimation() { + List animators=new ArrayList<>(); + long[] delays=new long[]{500,250,0,250,500}; + for (int i = 0; i < 5; i++) { + final int index=i; + ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.3f,1); + scaleAnim.setDuration(900); + scaleAnim.setRepeatCount(-1); + scaleAnim.setStartDelay(delays[i]); + scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + scaleYFloats[index] = (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + scaleAnim.start(); + animators.add(scaleAnim); + } + return animators; + } + +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/LineScalePulseOutRapidIndicator.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/LineScalePulseOutRapidIndicator.java new file mode 100644 index 00000000..a26d94fb --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/LineScalePulseOutRapidIndicator.java @@ -0,0 +1,37 @@ +package com.rmondjone.xrecyclerview.progressindicator.indicator; + +import android.animation.Animator; +import android.animation.ValueAnimator; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Jack on 2015/10/19. + */ +public class LineScalePulseOutRapidIndicator extends LineScaleIndicator { + + @Override + public List createAnimation() { + List animators=new ArrayList<>(); + long[] delays=new long[]{400,200,0,200,400}; + for (int i = 0; i < 5; i++) { + final int index=i; + ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.4f,1); + scaleAnim.setDuration(1000); + scaleAnim.setRepeatCount(-1); + scaleAnim.setStartDelay(delays[i]); + scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + scaleYFloats[index] = (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + scaleAnim.start(); + animators.add(scaleAnim); + } + return animators; + } + +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/LineSpinFadeLoaderIndicator.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/LineSpinFadeLoaderIndicator.java new file mode 100644 index 00000000..403853cd --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/LineSpinFadeLoaderIndicator.java @@ -0,0 +1,30 @@ +package com.rmondjone.xrecyclerview.progressindicator.indicator; + +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.RectF; + +/** + * Created by Jack on 2015/10/24. + * Email:81813780@qq.com + */ +public class LineSpinFadeLoaderIndicator extends BallSpinFadeLoaderIndicator { + + + @Override + public void draw(Canvas canvas, Paint paint) { + float radius=getWidth()/10; + for (int i = 0; i < 8; i++) { + canvas.save(); + Point point=circleAt(getWidth(),getHeight(),getWidth()/2.5f-radius,i*(Math.PI/4)); + canvas.translate(point.x, point.y); + canvas.scale(scaleFloats[i], scaleFloats[i]); + canvas.rotate(i*45); + paint.setAlpha(alphas[i]); + RectF rectF=new RectF(-radius,-radius/1.5f,1.5f*radius,radius/1.5f); + canvas.drawRoundRect(rectF,5,5,paint); + canvas.restore(); + } + } + +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/PacmanIndicator.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/PacmanIndicator.java new file mode 100644 index 00000000..65c7397b --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/PacmanIndicator.java @@ -0,0 +1,119 @@ +package com.rmondjone.xrecyclerview.progressindicator.indicator; + +import android.animation.Animator; +import android.animation.ValueAnimator; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.RectF; +import android.view.animation.LinearInterpolator; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Jack on 2015/10/16. + */ +public class PacmanIndicator extends BaseIndicatorController{ + + private float translateX; + + private int alpha; + + private float degrees1,degrees2; + + @Override + public void draw(Canvas canvas, Paint paint) { + drawPacman(canvas,paint); + drawCircle(canvas,paint); + } + + private void drawPacman(Canvas canvas,Paint paint){ + float x=getWidth()/2; + float y=getHeight()/2; + + canvas.save(); + + canvas.translate(x, y); + canvas.rotate(degrees1); + paint.setAlpha(255); + RectF rectF1=new RectF(-x/1.7f,-y/1.7f,x/1.7f,y/1.7f); + canvas.drawArc(rectF1, 0, 270, true, paint); + + canvas.restore(); + + canvas.save(); + canvas.translate(x, y); + canvas.rotate(degrees2); + paint.setAlpha(255); + RectF rectF2=new RectF(-x/1.7f,-y/1.7f,x/1.7f,y/1.7f); + canvas.drawArc(rectF2,90,270,true,paint); + canvas.restore(); + } + + + private void drawCircle(Canvas canvas, Paint paint) { + float radius=getWidth()/11; + paint.setAlpha(alpha); + canvas.drawCircle(translateX, getHeight() / 2, radius, paint); + } + + @Override + public List createAnimation() { + List animators=new ArrayList<>(); + float startT=getWidth()/11; + ValueAnimator translationAnim=ValueAnimator.ofFloat(getWidth()-startT,getWidth()/2); + translationAnim.setDuration(650); + translationAnim.setInterpolator(new LinearInterpolator()); + translationAnim.setRepeatCount(-1); + translationAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + translateX = (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + translationAnim.start(); + + ValueAnimator alphaAnim=ValueAnimator.ofInt(255,122); + alphaAnim.setDuration(650); + alphaAnim.setRepeatCount(-1); + alphaAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + alpha = (int) animation.getAnimatedValue(); + postInvalidate(); + } + }); + alphaAnim.start(); + + ValueAnimator rotateAnim1=ValueAnimator.ofFloat(0, 45, 0); + rotateAnim1.setDuration(650); + rotateAnim1.setRepeatCount(-1); + rotateAnim1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + degrees1 = (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + rotateAnim1.start(); + + ValueAnimator rotateAnim2=ValueAnimator.ofFloat(0,-45,0); + rotateAnim2.setDuration(650); + rotateAnim2.setRepeatCount(-1); + rotateAnim2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + degrees2 = (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + rotateAnim2.start(); + + animators.add(translationAnim); + animators.add(alphaAnim); + animators.add(rotateAnim1); + animators.add(rotateAnim2); + return animators; + } +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/SemiCircleSpinIndicator.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/SemiCircleSpinIndicator.java new file mode 100644 index 00000000..0b0ea274 --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/SemiCircleSpinIndicator.java @@ -0,0 +1,36 @@ +package com.rmondjone.xrecyclerview.progressindicator.indicator; + +import android.animation.Animator; +import android.animation.ObjectAnimator; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.RectF; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Jack on 2015/10/20. + */ +public class SemiCircleSpinIndicator extends BaseIndicatorController { + + + @Override + public void draw(Canvas canvas, Paint paint) { + RectF rectF=new RectF(0,0,getWidth(),getHeight()); + canvas.drawArc(rectF,-60,120,false,paint); + } + + @Override + public List createAnimation() { + List animators=new ArrayList<>(); + ObjectAnimator rotateAnim=ObjectAnimator.ofFloat(getTarget(),"rotation",0,180,360); + rotateAnim.setDuration(600); + rotateAnim.setRepeatCount(-1); + rotateAnim.start(); + animators.add(rotateAnim); + return animators; + } + + +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/SquareSpinIndicator.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/SquareSpinIndicator.java new file mode 100644 index 00000000..68bc7231 --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/SquareSpinIndicator.java @@ -0,0 +1,37 @@ +package com.rmondjone.xrecyclerview.progressindicator.indicator; + +import android.animation.Animator; +import android.animation.ObjectAnimator; +import android.animation.PropertyValuesHolder; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.RectF; +import android.view.animation.LinearInterpolator; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Jack on 2015/10/16. + */ +public class SquareSpinIndicator extends BaseIndicatorController { + + @Override + public void draw(Canvas canvas, Paint paint) { + canvas.drawRect(new RectF(getWidth()/5,getHeight()/5,getWidth()*4/5,getHeight()*4/5),paint); + } + + @Override + public List createAnimation() { + List animators=new ArrayList<>(); + PropertyValuesHolder rotation5=PropertyValuesHolder.ofFloat("rotationX",0,180,180,0,0); + PropertyValuesHolder rotation6=PropertyValuesHolder.ofFloat("rotationY",0,0,180,180,0); + ObjectAnimator animator=ObjectAnimator.ofPropertyValuesHolder(getTarget(), rotation6,rotation5); + animator.setInterpolator(new LinearInterpolator()); + animator.setRepeatCount(-1); + animator.setDuration(2500); + animator.start(); + animators.add(animator); + return animators; + } +} diff --git a/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/TriangleSkewSpinIndicator.java b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/TriangleSkewSpinIndicator.java new file mode 100644 index 00000000..7a0e6472 --- /dev/null +++ b/locktableview/src/main/java/com/rmondjone/xrecyclerview/progressindicator/indicator/TriangleSkewSpinIndicator.java @@ -0,0 +1,45 @@ +package com.rmondjone.xrecyclerview.progressindicator.indicator; + +import android.animation.Animator; +import android.animation.ObjectAnimator; +import android.animation.PropertyValuesHolder; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Path; +import android.view.animation.LinearInterpolator; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Jack on 2015/10/20. + */ +public class TriangleSkewSpinIndicator extends BaseIndicatorController { + + @Override + public void draw(Canvas canvas, Paint paint) { + Path path=new Path(); + path.moveTo(getWidth()/5,getHeight()*4/5); + path.lineTo(getWidth()*4/5, getHeight()*4/5); + path.lineTo(getWidth()/2,getHeight()/5); + path.close(); + canvas.drawPath(path, paint); + } + + @Override + public List createAnimation() { + List animators=new ArrayList<>(); + PropertyValuesHolder rotation5=PropertyValuesHolder.ofFloat("rotationX",0,180,180,0,0); + PropertyValuesHolder rotation6=PropertyValuesHolder.ofFloat("rotationY",0,0,180,180,0); + + ObjectAnimator animator=ObjectAnimator.ofPropertyValuesHolder(getTarget(), rotation6,rotation5); + animator.setInterpolator(new LinearInterpolator()); + animator.setRepeatCount(-1); + animator.setDuration(2500); + animator.start(); + + animators.add(animator); + return animators; + } + +} diff --git a/locktableview/src/main/res/drawable/ic_loading_rotate.png b/locktableview/src/main/res/drawable/ic_loading_rotate.png new file mode 100644 index 00000000..f0a4bfeb Binary files /dev/null and b/locktableview/src/main/res/drawable/ic_loading_rotate.png differ diff --git a/locktableview/src/main/res/drawable/ic_pulltorefresh_arrow.png b/locktableview/src/main/res/drawable/ic_pulltorefresh_arrow.png new file mode 100644 index 00000000..511fa319 Binary files /dev/null and b/locktableview/src/main/res/drawable/ic_pulltorefresh_arrow.png differ diff --git a/locktableview/src/main/res/drawable/iconfont_downgrey.png b/locktableview/src/main/res/drawable/iconfont_downgrey.png new file mode 100644 index 00000000..42e1371c Binary files /dev/null and b/locktableview/src/main/res/drawable/iconfont_downgrey.png differ diff --git a/locktableview/src/main/res/drawable/loading_01.png b/locktableview/src/main/res/drawable/loading_01.png new file mode 100644 index 00000000..1c190a99 Binary files /dev/null and b/locktableview/src/main/res/drawable/loading_01.png differ diff --git a/locktableview/src/main/res/drawable/loading_02.png b/locktableview/src/main/res/drawable/loading_02.png new file mode 100644 index 00000000..bc930f2d Binary files /dev/null and b/locktableview/src/main/res/drawable/loading_02.png differ diff --git a/locktableview/src/main/res/drawable/loading_03.png b/locktableview/src/main/res/drawable/loading_03.png new file mode 100644 index 00000000..e461335e Binary files /dev/null and b/locktableview/src/main/res/drawable/loading_03.png differ diff --git a/locktableview/src/main/res/drawable/loading_04.png b/locktableview/src/main/res/drawable/loading_04.png new file mode 100644 index 00000000..071af1ed Binary files /dev/null and b/locktableview/src/main/res/drawable/loading_04.png differ diff --git a/locktableview/src/main/res/drawable/loading_05.png b/locktableview/src/main/res/drawable/loading_05.png new file mode 100644 index 00000000..43ba85ff Binary files /dev/null and b/locktableview/src/main/res/drawable/loading_05.png differ diff --git a/locktableview/src/main/res/drawable/loading_06.png b/locktableview/src/main/res/drawable/loading_06.png new file mode 100644 index 00000000..67c6faa1 Binary files /dev/null and b/locktableview/src/main/res/drawable/loading_06.png differ diff --git a/locktableview/src/main/res/drawable/loading_07.png b/locktableview/src/main/res/drawable/loading_07.png new file mode 100644 index 00000000..797c5d8a Binary files /dev/null and b/locktableview/src/main/res/drawable/loading_07.png differ diff --git a/locktableview/src/main/res/drawable/loading_08.png b/locktableview/src/main/res/drawable/loading_08.png new file mode 100644 index 00000000..bbeecf25 Binary files /dev/null and b/locktableview/src/main/res/drawable/loading_08.png differ diff --git a/locktableview/src/main/res/drawable/loading_09.png b/locktableview/src/main/res/drawable/loading_09.png new file mode 100644 index 00000000..397c08da Binary files /dev/null and b/locktableview/src/main/res/drawable/loading_09.png differ diff --git a/locktableview/src/main/res/drawable/loading_10.png b/locktableview/src/main/res/drawable/loading_10.png new file mode 100644 index 00000000..2c4c58b2 Binary files /dev/null and b/locktableview/src/main/res/drawable/loading_10.png differ diff --git a/locktableview/src/main/res/drawable/loading_11.png b/locktableview/src/main/res/drawable/loading_11.png new file mode 100644 index 00000000..587c1df6 Binary files /dev/null and b/locktableview/src/main/res/drawable/loading_11.png differ diff --git a/locktableview/src/main/res/drawable/loading_12.png b/locktableview/src/main/res/drawable/loading_12.png new file mode 100644 index 00000000..162ffd46 Binary files /dev/null and b/locktableview/src/main/res/drawable/loading_12.png differ diff --git a/locktableview/src/main/res/drawable/progressbar.xml b/locktableview/src/main/res/drawable/progressbar.xml new file mode 100644 index 00000000..1a1ad5c0 --- /dev/null +++ b/locktableview/src/main/res/drawable/progressbar.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/locktableview/src/main/res/drawable/progressloading.xml b/locktableview/src/main/res/drawable/progressloading.xml new file mode 100644 index 00000000..20bc7b82 --- /dev/null +++ b/locktableview/src/main/res/drawable/progressloading.xml @@ -0,0 +1,3 @@ + + \ No newline at end of file diff --git a/locktableview/src/main/res/layout/listview_footer.xml b/locktableview/src/main/res/layout/listview_footer.xml new file mode 100644 index 00000000..4faaa0cd --- /dev/null +++ b/locktableview/src/main/res/layout/listview_footer.xml @@ -0,0 +1,21 @@ + + + + + + \ No newline at end of file diff --git a/locktableview/src/main/res/layout/listview_header.xml b/locktableview/src/main/res/layout/listview_header.xml new file mode 100644 index 00000000..4bacbcab --- /dev/null +++ b/locktableview/src/main/res/layout/listview_header.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/locktableview/src/main/res/layout/lock_item.xml b/locktableview/src/main/res/layout/lock_item.xml new file mode 100644 index 00000000..3e6c260b --- /dev/null +++ b/locktableview/src/main/res/layout/lock_item.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/locktableview/src/main/res/layout/locktablecontentview.xml b/locktableview/src/main/res/layout/locktablecontentview.xml new file mode 100644 index 00000000..f3dd442c --- /dev/null +++ b/locktableview/src/main/res/layout/locktablecontentview.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + diff --git a/locktableview/src/main/res/layout/locktableview.xml b/locktableview/src/main/res/layout/locktableview.xml new file mode 100644 index 00000000..a5a234eb --- /dev/null +++ b/locktableview/src/main/res/layout/locktableview.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/locktableview/src/main/res/layout/pull_to_refresh_head.xml b/locktableview/src/main/res/layout/pull_to_refresh_head.xml new file mode 100644 index 00000000..74a30552 --- /dev/null +++ b/locktableview/src/main/res/layout/pull_to_refresh_head.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/locktableview/src/main/res/layout/unlock_item.xml b/locktableview/src/main/res/layout/unlock_item.xml new file mode 100644 index 00000000..353f3984 --- /dev/null +++ b/locktableview/src/main/res/layout/unlock_item.xml @@ -0,0 +1,14 @@ + + + + + + \ No newline at end of file diff --git a/locktableview/src/main/res/values-zh/strings.xml b/locktableview/src/main/res/values-zh/strings.xml new file mode 100644 index 00000000..dbda8c72 --- /dev/null +++ b/locktableview/src/main/res/values-zh/strings.xml @@ -0,0 +1,10 @@ + + 下拉刷新 + 释放立即刷新 + 正在加载... + 数据已全部加载结束 + 正在刷新... + 刷新完成 + 加载完成 + 上次更新时间: + diff --git a/locktableview/src/main/res/values/attrs.xml b/locktableview/src/main/res/values/attrs.xml new file mode 100644 index 00000000..96d1b7d5 --- /dev/null +++ b/locktableview/src/main/res/values/attrs.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/locktableview/src/main/res/values/colors.xml b/locktableview/src/main/res/values/colors.xml new file mode 100644 index 00000000..e7018ab9 --- /dev/null +++ b/locktableview/src/main/res/values/colors.xml @@ -0,0 +1,56 @@ + + + + + #00000000 + #334E6C + #E5EFFE + #FF000000 + #FFFFFFFF + #e6e6e6 + #fafafa + #555555 + #FF0033 + #ADD8E6 + #817F80 + #0000ff + #00000000 + #0F0 + #FF0000 + #DDDDDD + #b8b8b8 + #0cb9f5 + #2c8fd3 + #ffa500 + #000000 + #e3eef4 + #b1dce2ff + #faedda + #ff6bd697 + #c0c0c0 + #FFf3feff + #FFfff1f2 + #603b07 + #00000000 + #31abfe + #76c120 + #ffffffff + #EE4000 + #fff2f9ec + #EDEDE4 + #E8E8E8 + #ff434343 + #FAFAFA + #3C70A6 + #C3C4C9 + #262B31 + #CED7DF + #7B7B7B + #949494 + #1989E0 + #CFEDF9 + #FFFFFF + #F7F8F9 + #C2C0C2 + + \ No newline at end of file diff --git a/locktableview/src/main/res/values/dimens.xml b/locktableview/src/main/res/values/dimens.xml new file mode 100644 index 00000000..1fe58b1f --- /dev/null +++ b/locktableview/src/main/res/values/dimens.xml @@ -0,0 +1,4 @@ + + + 10dp + diff --git a/locktableview/src/main/res/values/strings.xml b/locktableview/src/main/res/values/strings.xml new file mode 100644 index 00000000..75b99226 --- /dev/null +++ b/locktableview/src/main/res/values/strings.xml @@ -0,0 +1,10 @@ + + pull to refresh + release to start refresh + loading... + no more to be loaded + refreshing... + refresh done + loading done + last update: + diff --git a/moduleUtil/build.gradle b/moduleUtil/build.gradle index 6b0a82b8..0e3a6e05 100644 --- a/moduleUtil/build.gradle +++ b/moduleUtil/build.gradle @@ -67,6 +67,8 @@ dependencies { implementation project(':moduletablayout') implementation libs.activity implementation libs.constraintlayout + api 'androidx.activity:activity-compose:1.8.2' + testImplementation libs.junit androidTestImplementation libs.ext.junit androidTestImplementation libs.espresso.core diff --git a/moduleUtil/src/main/assets/mic.svga b/moduleUtil/src/main/assets/mic.svga new file mode 100644 index 00000000..f299ecab Binary files /dev/null and b/moduleUtil/src/main/assets/mic.svga differ diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/adapter/CirleListAdapter.java b/moduleUtil/src/main/java/com/xscm/moduleutil/adapter/CirleListAdapter.java index 39b071b5..bd5af6ab 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/adapter/CirleListAdapter.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/adapter/CirleListAdapter.java @@ -4,6 +4,7 @@ import static android.view.View.GONE; import static android.view.View.VISIBLE; import static com.blankj.utilcode.util.ActivityUtils.startActivity; +import android.graphics.Color; import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.TextPaint; @@ -128,7 +129,7 @@ public class CirleListAdapter extends BaseQuickAdapter mDatas; private final LayoutInflater inflater; @@ -110,39 +113,6 @@ public class GiftRoomAdapter extends BaseAdapter { this.mDatas.addAll(newData); } - -// private static class MyGestureDetector extends GestureDetector { -// private GiftRoomAdapter mAdapter; -// private RoonGiftModel mGiftModel; -// -// public MyGestureDetector(Context context) { -// super(context, new SimpleOnGestureListener() { -// @Override -// public boolean onSingleTapConfirmed(MotionEvent e) { -// if (mAdapter != null && mGiftModel != null) { -// EventBus.getDefault().post(new RoomGiftClickToEvent(mAdapter, mGiftModel, 1)); -// } -// return true; -// } -// -// @Override -// public boolean onDoubleTap(MotionEvent e) { -// if (mAdapter != null && mGiftModel != null) { -// EventBus.getDefault().post(new RoomGiftClickToEvent(mAdapter, mGiftModel, 2)); -// } -// return true; -// } -// }); -// setOnDoubleTapListener(getListener()); -// } -// -// public void setGiftModel(GiftRoomAdapter adapter, RoonGiftModel giftModel) { -// this.mAdapter = adapter; -// this.mGiftModel = giftModel; -// } -// } - - @Override @SuppressLint({"SetTextI18n", "ClickableViewAccessibility"}) public View getView(int position, View convertView, ViewGroup parent) { @@ -157,7 +127,7 @@ public class GiftRoomAdapter extends BaseAdapter { viewHolder.item_layout = (ConstraintLayout) convertView.findViewById(R.id.cl_gift); viewHolder.ivDownOn = (ImageView) convertView.findViewById(R.id.iv_down_on); viewHolder.cl_iv_down_on = (ConstraintLayout) convertView.findViewById(R.id.cl_iv_down_on); - + viewHolder.iv_gift_select= (ImageView) convertView.findViewById(R.id.iv_gift_select); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); @@ -165,10 +135,18 @@ public class GiftRoomAdapter extends BaseAdapter { viewHolder.item_layout.setOnClickListener(v -> { // RoonGiftModel clickedModel = (RoonGiftModel) v.getTag(); - EventBus.getDefault().post(new RoomGiftClickToEvent(this, giftModel, 1)); + if (giftModel.getIs_lock()==0) { + EventBus.getDefault().post(new RoomGiftClickToEvent(this, giftModel, 1)); + }else if (giftModel.getIs_lock()==1){ + ToastUtils.show("当前属于爵位礼物,请开通爵位"); + } }); - + if (giftModel.getIs_lock()==0){ + viewHolder.iv_gift_select.setVisibility(GONE); + }else { + viewHolder.iv_gift_select.setVisibility(View.VISIBLE); + } /* * 在给View绑定显示的数据时,计算正确的position = position + curIndex * pageSize, */ @@ -193,9 +171,9 @@ public class GiftRoomAdapter extends BaseAdapter { if (giftModel.isChecked()) {//被选中 viewHolder.cl_iv_down_on.setBackgroundResource(R.mipmap.room_gift_bjx); - viewHolder.ivDownOn.setVisibility(View.GONE); + viewHolder.ivDownOn.setVisibility(GONE); } else { - viewHolder.ivDownOn.setVisibility(View.GONE); + viewHolder.ivDownOn.setVisibility(GONE); viewHolder.cl_iv_down_on.setBackgroundResource(0); } //设置 @@ -234,6 +212,7 @@ public class GiftRoomAdapter extends BaseAdapter { public ImageView iv_gift_pic; public TextView tv_gift_change_love_values; public ImageView ivDownOn; + public ImageView iv_gift_select; public ConstraintLayout cl_iv_down_on; } } diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/base/CommonAppContext.java b/moduleUtil/src/main/java/com/xscm/moduleutil/base/CommonAppContext.java index 8372aaae..9d84a1cc 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/base/CommonAppContext.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/base/CommonAppContext.java @@ -164,7 +164,6 @@ public class CommonAppContext extends MultiDexApplication implements Applicatio // 全局设置字体不缩放 adjustFontScale(getResources().getConfiguration()); CrashHandler.init(this); - // if (currentEnvironment.getShelf()==1){ if (SpUtil.getShelf()!=0) { SpUtil.setShelf(0); @@ -798,7 +797,7 @@ public class CommonAppContext extends MultiDexApplication implements Applicatio @Override public RefreshHeader createRefreshHeader(Context context, RefreshLayout layout) { ClassicsHeader header = new ClassicsHeader(context); - header.setDrawableSize(20); + header.setDrawableSize(10); header.setFinishDuration(0); return header;//.setTimeFormat(new DynamicTimeFormat("更新于 %s"));//指定为经典Header,默认是 贝塞尔雷达Header // return new CustomRefreshHeader(context);//.setTimeFormat(new DynamicTimeFormat("更新于 %s"));//指定为经典Header,默认是 贝塞尔雷达Header @@ -809,7 +808,7 @@ public class CommonAppContext extends MultiDexApplication implements Applicatio @Override public RefreshFooter createRefreshFooter(Context context, RefreshLayout layout) { ClassicsFooter classicsFooter = new ClassicsFooter(context); - classicsFooter.setDrawableSize(20); + classicsFooter.setDrawableSize(10); classicsFooter.setFinishDuration(0); //指定为经典Footer,默认是 BallPulseFooter return classicsFooter; diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/base/RoomManager.java b/moduleUtil/src/main/java/com/xscm/moduleutil/base/RoomManager.java index 5feb32d3..4a2b27bf 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/base/RoomManager.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/base/RoomManager.java @@ -146,57 +146,9 @@ public class RoomManager { return; } isUserOnline(context, roomId, password, roomInfo,taskId); - +// fetchAndJoinRoom(context, roomId, password,taskId); } -// try { -// Thread.sleep(1000); -// } catch (InterruptedException e) { -// Thread.currentThread().interrupt(); -// } - - // 如果是当前房间且用户在线,直接跳转到房间页面,仅更新数据 - - -// // 获取房间数据 -// MessageListenerSingleton.getInstance().joinGroup(roomId); -// // 等待一段时间确保退出完成 -// try { -// Thread.sleep(500); -// } catch (InterruptedException e) { -// Thread.currentThread().interrupt(); -// } -// RetrofitClient.getInstance().roomGetIn(roomId, password, new BaseObserver() { -// -// @Override -// public void onSubscribe(Disposable d) { -// } -// -// @Override -// public void onNext(RoomInfoResp resp) { -// String appId = CommonAppContext.getInstance().getCurrentEnvironment().getSwSdkAppId(); -// String token = resp.getUser_info().getAgora_token(); // 如果启用了鉴权才需要 -// String roomId = resp.getRoom_info().getRoom_id(); // 房间 ID -// String rtm_token=resp.getUser_info().getAgora_rtm_token(); -// SpUtil.setRtmToken(rtm_token); -// int uid = SpUtil.getUserId(); // 0 表示由 Agora 自动生成 UID -// boolean enableMic = false; // 是否开启麦克风 -// boolean enableJs=false; // 是否开启角色 -// if (resp.getUser_info().getPit_number()!=0){ -// enableJs=true; -// } -// LogUtils.e("token",token); -// LogUtils.e("roomId:",roomId); -//// 初始化 Agora 并加入房间 -// AgoraManager.getInstance(context) -// .joinRoom(token, roomId, uid, enableMic,enableJs); -// cacheRoomData(roomId, resp); -// navigateToRoom(context, roomId, password, resp); -// } -// }); - - // 临时实现 - 直接跳转(因为缺少具体的网络请求代码) -// navigateToRoom(context, roomId, password, null); } private void upInfo(Context context, String roomId, String password, boolean isOnline, RoomInfoResp roomInfo, boolean isCurrentRoom,String taskId) { @@ -265,8 +217,6 @@ public class RoomManager { .joinRoom(token, roomId, uid, enableMic, enableJs); cacheRoomData(roomId, resp); navigateToRoom(context, roomId, password, resp, false, taskId); - }else { - } } diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/bean/CircleListBean.java b/moduleUtil/src/main/java/com/xscm/moduleutil/bean/CircleListBean.java index d205aed6..d1632e74 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/bean/CircleListBean.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/bean/CircleListBean.java @@ -31,6 +31,10 @@ public class CircleListBean { private String share_url; private List title;//话题列表 + private String nobility_image;//贵族图标 + private String nickname_color;//昵称颜色 + private String mic_cycle;//麦圈 + private String read_num;//阅读数 private List like_list; diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/bean/ExpandColumnBean.java b/moduleUtil/src/main/java/com/xscm/moduleutil/bean/ExpandColumnBean.java index ffb7a481..81ace5ca 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/bean/ExpandColumnBean.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/bean/ExpandColumnBean.java @@ -20,5 +20,6 @@ public class ExpandColumnBean { private int room_id;//房间id,当有参数的时候,就显示跟随,当没有的时候,就显示私信控件 private String agree; private List icon; - + private String nobility_image;//贵族图标 + private String nickname_color;//昵称颜色 } diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/bean/MusicSongBean.java b/moduleUtil/src/main/java/com/xscm/moduleutil/bean/MusicSongBean.java index 29dfa79c..4f145ed5 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/bean/MusicSongBean.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/bean/MusicSongBean.java @@ -25,4 +25,8 @@ public class MusicSongBean implements Serializable { private String dress; private String charm; private int is_hot;//是否是主持,并且是在9号麦位上 + + private String nobility_image;//贵族图标 + private String nickname_color;//昵称颜色 + private String mic_cycle;//麦圈 } diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/bean/NobilitDeatils.kt b/moduleUtil/src/main/java/com/xscm/moduleutil/bean/NobilitDeatils.kt new file mode 100644 index 00000000..3e6c3260 --- /dev/null +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/bean/NobilitDeatils.kt @@ -0,0 +1,82 @@ +package com.xscm.moduleutil.bean + +/** + *com.xscm.moduleutil.bean + *qx + *2025/11/8 + * + */ +class NobilitDeatils { + + var nobility_power_list = ArrayList() + var user_info: UserInfo? = null + var nobility_info: NobilityInfo? = null + + class UserInfo { + /*"user_info": { // 用户信息 + "id": 20034, //用户Id + "nickname": "奋斗的石头", //用户昵称 + "avatar": "http://test.vespa.qxyushen.top/data/avatar/head_pic.png" //用户头像 + }*/ + var id: Int = 0 + var nickname: String = "" + var avatar: String = "" + } + + class NobilityInfo { + /*"nobility_info": { // 爵位信息 + "status": 0, //状态: 0去开通 1去续费 + "lid": 0, //爵位ID + "name": "", // 爵位名称 + "image": "", //爵位图片 + "end_time": 0 //结束时间 + }*/ + var status: Int = 0 + var name: String = "" + var lid: Int = 0 + var image: String = "" + var end_time: String = "" + } + + class nobilityPowerItem { + /*"lid": 0, //爵位ID + "name": "特权", //爵位名称 + "power_ids": "", //权限ID + "nick_name_color": "无", //昵称颜色 + "nick_name_color_name": "无", //昵称颜色名称 + "nobility_list": [ + { + "id": 1, //权限ID + "name": "专属徽章", //权限名称 + "image": "", //权限图片 + "status": 0 //权限状态 : 0 不显示 1显示 + }, + { + "id": 2, + "name": "昵称颜色", + "image": "", + "status": 0 + } + + ]*/ + + var lid: Int = 0 + var name: String = "" + var power_ids: String = "" + var nick_name_color: String = "" + var nick_name_color_name: String = "" + var nobility_list = ArrayList() + + class nobilityPowerItem { + /*"id": 1, //权限ID + "name": "专属徽章", //权限名称 + "image": "", //权限图片 + "status": 0 //权限状态 : 0 不显示 1显示*/ + var id: Int = 0 + var name: String = "" + var image: String = "" + var status: Int = 0 + } + + } +} \ No newline at end of file diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/bean/NobilitList.kt b/moduleUtil/src/main/java/com/xscm/moduleutil/bean/NobilitList.kt new file mode 100644 index 00000000..4c9dc55f --- /dev/null +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/bean/NobilitList.kt @@ -0,0 +1,51 @@ +package com.xscm.moduleutil.bean + +/** + *com.xscm.moduleutil.bean + *qx + *2025/11/10 + * + */ +class NobilitList { + + var name: String = "" + var image: String = "" + var pay_price: String = "" + var power: Power? = Power() + var lid: Int = 0 + var day : Int = 0 + class Power { + var power_count: Int = 0 + var this_power_count: Int = 0 + var count_str: String = "" + var list = ArrayList() + + class PowerItem { + var id: Int = 0 + var name: String = "" + var content: String = "" + var image: String = "" + } + } + + + /* { + "name": "骑士", + "image": "https://cos.xscmmidi.site/admin/ScreenShot_2025-11-05_175044_144_17623369241246.png", + "pay_price": "388.00", + "power": { + "power_count": 12, + "this_power_count": 1, + "count_str": "12/1", + "list": [ + { + "id": 1, + "name": "专属徽章", + "content": "专属动态爵位徽章", + "image": "" + } + ] + } + }, + */ +} \ No newline at end of file diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/bean/NobilityPrice.kt b/moduleUtil/src/main/java/com/xscm/moduleutil/bean/NobilityPrice.kt new file mode 100644 index 00000000..a2792c3b --- /dev/null +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/bean/NobilityPrice.kt @@ -0,0 +1,49 @@ +package com.xscm.moduleutil.bean + +/** + *com.xscm.moduleutil.bean + *qx + *2025/11/10 + * + */ +class NobilityPrice { + var lid : Int = 0 + var nobility_name : String = "" + var nobility_image : String = "" + var price : String = "" + var pay_price : String = "" + var day : Int = 0 + var end_time : String = "" + var power_list = ArrayList() + + class PowerItem { + var id : Int = 0 + var content : String = "" + } + + /* "lid": 2, + "nobility_name": "男爵", + "nobility_image": "https://cos.xscmmidi.site/admin/ScreenShot_2025-11-05_175121_076_17623369074684.png", + "price": "588.00", //实付价格 + "pay_price": "588.00", //画线价格 + "day": 30, + "power_list": [ + { + "id": 1, + "content": "专属动态爵位徽章" + }, + { + "id": 2, + "content": "设置昵称颜色字体" + }, + { + "id": 3, + "content": "特殊入场动画音效" + }, + { + "id": 4, + "content": "入场专属座驾动画" + } + ], + "end_time": "2025-12-10 10:19:20"*/ +} \ No newline at end of file diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/bean/RoonGiftModel.java b/moduleUtil/src/main/java/com/xscm/moduleutil/bean/RoonGiftModel.java index 10b31fb3..7ba275f2 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/bean/RoonGiftModel.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/bean/RoonGiftModel.java @@ -33,6 +33,7 @@ public class RoonGiftModel { private int num;//礼物数量 private int activities_id;//4:盲盒 ;5:天空之境; private int gift_bag;//10:天空之境 11:岁月之城 12:时空之巅 + private int is_lock;//爵位礼物 0:不锁 1:锁 public boolean isCan_send_self() { if ( isManghe()) { return true; diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/bean/TableCellData.kt b/moduleUtil/src/main/java/com/xscm/moduleutil/bean/TableCellData.kt new file mode 100644 index 00000000..76b87a5f --- /dev/null +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/bean/TableCellData.kt @@ -0,0 +1,12 @@ +package com.xscm.moduleutil.bean + +/** + *com.xscm.moduleutil.bean + *qx + *2025/11/8 + * + */ +class TableCellData { + var title: String = "" + var color: String = "" +} \ No newline at end of file diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/bean/UserInfo.java b/moduleUtil/src/main/java/com/xscm/moduleutil/bean/UserInfo.java index 5a882fb6..f38de927 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/bean/UserInfo.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/bean/UserInfo.java @@ -68,6 +68,15 @@ public class UserInfo implements Serializable { private String red_num; private String ta; + private String nobility_image;//贵族图标 + private String nickname_color;//昵称颜色 + private String mic_cycle;//麦圈 + private String is_hide;//0不能设置,1:可以设置 + private String hide_status;//0-取消隐身,1-设置隐身 + + private String enter_image;//爵位飘屏的背景 + private String enter_text;//爵位飘屏的文字 + // @Data diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/bean/room/EmotionDeatils.kt b/moduleUtil/src/main/java/com/xscm/moduleutil/bean/room/EmotionDeatils.kt index a2007b0c..bf23030d 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/bean/room/EmotionDeatils.kt +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/bean/room/EmotionDeatils.kt @@ -6,6 +6,7 @@ data class EmotionDeatils( var type_id: Int? = 0, var name: String? = "", var image: String? = "", + var is_lock: Int? = 0,//0:未锁定 1:锁定 var animate_image : String? = "", var children: List? =ArrayList (), ) @@ -17,4 +18,5 @@ data class Children( var name: String? = "", var image: String? = "", var animate_image : String? = "", + var is_lock: Int? = 0,//0:未锁定 1:锁定 ) \ No newline at end of file diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/bean/room/RoomAuction.java b/moduleUtil/src/main/java/com/xscm/moduleutil/bean/room/RoomAuction.java index 04aed59c..513fd213 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/bean/room/RoomAuction.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/bean/room/RoomAuction.java @@ -37,6 +37,9 @@ public class RoomAuction implements Serializable { private String base_image;//礼物图片 private long duration;//时间 private String charm; + private String nobility_image;//贵族图标 + private String nickname_color;//昵称颜色 + private String mic_cycle;//麦圈 } @Data diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/bean/room/RoomInfoResp.java b/moduleUtil/src/main/java/com/xscm/moduleutil/bean/room/RoomInfoResp.java index 0729ea36..249af8be 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/bean/room/RoomInfoResp.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/bean/room/RoomInfoResp.java @@ -5,6 +5,7 @@ import com.xscm.moduleutil.bean.MusicSongBean; import java.io.Serializable; import java.util.List; +import com.xscm.moduleutil.bean.NobilitDeatils; import lombok.Data; /** @@ -31,6 +32,7 @@ public class RoomInfoResp implements Serializable { private FriendInfo friend_info; private GiftXlh gift_cycle; private int hour_ranking_open;//1:开启 0:关闭 + private NobilitDeatils.NobilityInfo nobility_info; //弹出麦位操作弹出 diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/bean/room/RoomPitBean.java b/moduleUtil/src/main/java/com/xscm/moduleutil/bean/room/RoomPitBean.java index 6f60bbeb..0d3bb838 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/bean/room/RoomPitBean.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/bean/room/RoomPitBean.java @@ -65,4 +65,8 @@ public class RoomPitBean implements Serializable { private int heartId; // "heartId": 4, private int heartNum; // "heartNum": 10510 + private String nobility_image;//贵族图标 + private String nickname_color;//昵称颜色 + private String mic_cycle;//麦圈 + } diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/bean/room/RoomUserBean.java b/moduleUtil/src/main/java/com/xscm/moduleutil/bean/room/RoomUserBean.java index 8efb1a23..72292e74 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/bean/room/RoomUserBean.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/bean/room/RoomUserBean.java @@ -39,6 +39,10 @@ public class RoomUserBean implements Serializable { private String is_mute;//是否在本房间禁言 1是 0否 private String is_mute_pit;//是否在本房间内禁麦 1是 0否 + private String nobility_image;//贵族图标 + private String nickname_color;//昵称颜色 + private String mic_cycle;//麦圈 + // private int banned; // private int favorite; // private int pit; diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/http/ApiServer.java b/moduleUtil/src/main/java/com/xscm/moduleutil/http/ApiServer.java index 63694719..09ed0ca2 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/http/ApiServer.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/http/ApiServer.java @@ -288,12 +288,11 @@ public interface ApiServer { @GET(Constants.GET_GIFT_LABEL) Call>> getGiftLabel(@Query("have_hot") String have_hot); + //获取礼物列表 @GET(Constants.GIFT_LIST) -//获取礼物列表 Call>> getGiftList(@Query("label") int label,@Query("room_id")String room_id); - @GET(Constants.TOPIC_LIST) -//获取话题 + @GET(Constants.TOPIC_LIST)//获取话题 Call>> topicList(@Query("page") String page, @Query("page_limit") String page_limit); @FormUrlEncoded @@ -357,6 +356,10 @@ public interface ApiServer { @POST(Constants.CANCEL) Call> cancel(@Field("token") String token); + @FormUrlEncoded + @POST(Constants.POST_MODIFY_HIDE_STATUS) + Call> getModifyHideStatus(@Field("hide_status") String hide_status); + @FormUrlEncoded @POST(Constants.DELETE_ZONE) Call> deleteZone(@Field("id") String id); @@ -512,7 +515,8 @@ public interface ApiServer { @Field("coin") String coin, @Field("type") String type, @Field("type_params") String type_params, - @Field("type_id") String type_id + @Field("type_id") String type_id, + @Field("nobility_id") String nobility_id ); @FormUrlEncoded @@ -753,6 +757,15 @@ public interface ApiServer { @POST(Constants.GIFT_SEND) Call> giftSend(@Field("send_id")String send_id); + @GET(Constants.GET_NOBILITY_DETAIL) + Call> getNobilityDetail(); + + @GET(Constants.GET_NOBILITY_LIST) + Call>> getNobilityList(); + + @GET(Constants.GET_NOBILITY_PRICE) + Call> getNobilityPrice(@Query("id") String id); + @GET(Constants.GET_BOX_GIFT_LIST_XLH) Call> getBoxGiftListXLH( @Query("room_id") String room_id); diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/http/RetrofitClient.java b/moduleUtil/src/main/java/com/xscm/moduleutil/http/RetrofitClient.java index 382920ed..4ed0b21d 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/http/RetrofitClient.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/http/RetrofitClient.java @@ -23,6 +23,7 @@ import com.xscm.moduleutil.bean.blindboxwheel.XlhDrawBean; import com.xscm.moduleutil.bean.room.*; import com.xscm.moduleutil.bean.zhuangb.ZhuangBanShangChengBean; import com.xscm.moduleutil.listener.MessageListenerSingleton; +import com.xscm.moduleutil.utils.PermissionUtil; import com.xscm.moduleutil.utils.SpUtil; import com.xscm.moduleutil.utils.SystemUtils; import com.xscm.moduleutil.utils.cos.TempKeyBean; @@ -810,7 +811,19 @@ public class RetrofitClient { @Override public void onResponse(Call call, Response response) { if (response.code() == 200) { - observer.onNext("任务完成"); + try { + String json = response.body().string(); + BaseModel baseModel = GsonUtils.fromJson(json, BaseModel.class); + if (baseModel.getCode() == 1) { + baseModel.setData(baseModel.getMsg()); + observer.onNext(baseModel.getData()); + } else { + com.hjq.toast.ToastUtils.show(baseModel.getMsg()); + } + + } catch (IOException e) { + e.printStackTrace(); + } } } @@ -1430,8 +1443,8 @@ public class RetrofitClient { }); } - public void getBanners(BaseObserver> observer) { - sApiServer.getBanners("3").enqueue(new Callback>>() { + public void getBanners(String s,BaseObserver> observer) { + sApiServer.getBanners(s).enqueue(new Callback>>() { @Override public void onResponse(Call>> call, Response>> response) { if (response.code() == 200) { @@ -2154,8 +2167,8 @@ public class RetrofitClient { // }); } - public void appPay(String user_id, String money, String coin, String type, String type_params, String type_id, BaseObserver observer) { - sApiServer.appPay(user_id, money, coin, type, type_params, type_id).enqueue(new Callback>() { + public void appPay(String user_id, String money, String coin, String type, String type_params, String type_id,String nobility_id, BaseObserver observer) { + sApiServer.appPay(user_id, money, coin, type, type_params, type_id,nobility_id).enqueue(new Callback>() { @Override public void onResponse(Call> call, Response> response) { if (response.code() == 200) { @@ -3411,6 +3424,20 @@ public class RetrofitClient { }); } + public void getModifyHideStatus(String hide_status, BaseObserver observer ){ + sApiServer.getModifyHideStatus(hide_status).enqueue(new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + onNextRetu(response, observer); + } + + @Override + public void onFailure(Call> call, Throwable t) { + t.printStackTrace(); + } + }); + } + public void getPostData(String new_password, String mobile, String code, String userId, BaseObserver observer) { sApiServer.getPostData(new_password, mobile, code, userId).enqueue(new Callback>() { @Override @@ -3964,6 +3991,87 @@ public class RetrofitClient { }); } + public void getNobilityDetail(BaseObserver observer){ + sApiServer.getNobilityDetail().enqueue(new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + if (response.code() == 200) { + BaseModel baseModel = response.body(); + if (baseModel.getCode() == 1) { + observer.onNext(baseModel.getData()); + }else if (baseModel.getCode() == 0){ + ToastUtils.showShort(baseModel.getMsg()); + }else if (baseModel.getCode() == 301){ + try { + ToastUtils.showShort(baseModel.getMsg()); + CommonAppContext.getInstance().clearLoginInfo(); + } catch (ClassNotFoundException e) { + } + } + } + } + @Override + public void onFailure(Call> call, Throwable t) { + t.printStackTrace(); + } + }); + + } + + public void getNobilityList(BaseObserver> observer){ + sApiServer.getNobilityList().enqueue(new Callback>>() { + @Override + public void onResponse(Call>> call, Response>> response) { + if (response.code() == 200) { + BaseModel> baseModel = response.body(); + if (baseModel.getCode() == 1) { + observer.onNext(baseModel.getData()); + }else if (baseModel.getCode() == 0){ + ToastUtils.showShort(baseModel.getMsg()); + }else if (baseModel.getCode() == 301){ + try { + ToastUtils.showShort(baseModel.getMsg()); + CommonAppContext.getInstance().clearLoginInfo(); + } catch (ClassNotFoundException e) { + } + } + } + } + + @Override + public void onFailure(Call>> call, Throwable t) { + t.printStackTrace(); + } + }); + } + + public void getNobilityPrice(String id, BaseObserver observer){ + sApiServer.getNobilityPrice(id).enqueue(new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + if (response.code() == 200) { + BaseModel baseModel = response.body(); + if (baseModel.getCode() == 1) { + observer.onNext(baseModel.getData()); + }else if (baseModel.getCode() == 0){ + ToastUtils.showShort(baseModel.getMsg()); + }else if (baseModel.getCode() == 301){ + try { + ToastUtils.showShort(baseModel.getMsg()); + CommonAppContext.getInstance().clearLoginInfo(); + } catch (ClassNotFoundException e) { + } + } + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + t.printStackTrace(); + } + }); + } + public void giftSend(String send_id, BaseObserver observer) { sApiServer.giftSend(send_id).enqueue(new Callback>() { @Override diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/listener/MessageListenerSingleton.java b/moduleUtil/src/main/java/com/xscm/moduleutil/listener/MessageListenerSingleton.java index e75a42fd..8813f3ff 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/listener/MessageListenerSingleton.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/listener/MessageListenerSingleton.java @@ -358,7 +358,7 @@ public class MessageListenerSingleton { // 等待退出操作完成,最多等待3秒 try { - quitLatch.await(3, java.util.concurrent.TimeUnit.SECONDS); + quitLatch.await(1, java.util.concurrent.TimeUnit.SECONDS); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } @@ -367,12 +367,6 @@ public class MessageListenerSingleton { } } - // 等待一段时间确保退出完成 - try { - Thread.sleep(200); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } // 加入新群组 LogUtils.d("MessageListener", "开始加入群组: " + roomId); @@ -413,7 +407,7 @@ public class MessageListenerSingleton { // 等待加入操作完成,最多等待3秒 try { - joinLatch.await(3, java.util.concurrent.TimeUnit.SECONDS); + joinLatch.await(1, java.util.concurrent.TimeUnit.SECONDS); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/presenter/RechargeDialogPresenter.java b/moduleUtil/src/main/java/com/xscm/moduleutil/presenter/RechargeDialogPresenter.java index a33e081e..4ddd5542 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/presenter/RechargeDialogPresenter.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/presenter/RechargeDialogPresenter.java @@ -48,7 +48,7 @@ public class RechargeDialogPresenter extends BasePresenter() { + api.appPay(user_id, money, coin, type,type_params,type_id,"", new BaseObserver() { @Override public void onSubscribe(Disposable d) { addDisposable(d); diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/utils/CrashHandler.java b/moduleUtil/src/main/java/com/xscm/moduleutil/utils/CrashHandler.java index de06982a..325cf840 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/utils/CrashHandler.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/utils/CrashHandler.java @@ -40,9 +40,9 @@ public class CrashHandler implements Thread.UncaughtExceptionHandler { private void restartApp() { // 实现应用重启逻辑 // ARouter.getInstance().build(ARouteConstants.ME).navigation(); - Intent intent = new Intent("com.qxcm.qxlive.LAUNCH_PAGE"); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(intent); + startActivity(intent); + } } diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/utils/GrayscaleTransformation.java b/moduleUtil/src/main/java/com/xscm/moduleutil/utils/GrayscaleTransformation.java new file mode 100644 index 00000000..47cea281 --- /dev/null +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/utils/GrayscaleTransformation.java @@ -0,0 +1,43 @@ +package com.xscm.moduleutil.utils; + +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.ColorMatrix; +import android.graphics.ColorMatrixColorFilter; +import android.graphics.Paint; + +import androidx.annotation.NonNull; + +import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; +import com.bumptech.glide.load.resource.bitmap.BitmapTransformation; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; + +public class GrayscaleTransformation extends BitmapTransformation { + + private Float saturation; + public GrayscaleTransformation(float saturation) { + super(); + this.saturation = saturation; + } + + @Override + protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) { + Bitmap result = pool.get(toTransform.getWidth(), toTransform.getHeight(), Bitmap.Config.ARGB_8888); + + Canvas canvas = new Canvas(result); + ColorMatrix colorMatrix = new ColorMatrix(); + colorMatrix.setSaturation(saturation); // 设置为灰度 + Paint paint = new Paint(); + paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix)); + canvas.drawBitmap(toTransform, 0, 0, paint); + + return result; + } + + @Override + public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) { + messageDigest.update("grayscale transformation".getBytes(StandardCharsets.UTF_8)); + } +} diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/utils/ImageLoader.java b/moduleUtil/src/main/java/com/xscm/moduleutil/utils/ImageLoader.java index 7fd7e627..4342cffe 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/utils/ImageLoader.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/utils/ImageLoader.java @@ -6,6 +6,7 @@ import android.text.TextUtils; import android.view.View; import android.widget.ImageView; +import com.bumptech.glide.GenericTransitionOptions; import com.bumptech.glide.Glide; import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.bumptech.glide.request.RequestOptions; @@ -14,7 +15,6 @@ import com.xscm.moduleutil.R; /** * Copyright (c) 1 - * */ public class ImageLoader { @@ -37,6 +37,17 @@ public class ImageLoader { public static void loadImage(Context context, ImageView view, String url) { Glide.with(context).load(url).error(R.mipmap.default_image).placeholder(R.mipmap.default_image).diskCacheStrategy(DiskCacheStrategy.ALL).into(view); } + /** + * 加载图片并灰度 + * @param context + * @param view + * @param url + * @param placeholder + */ + public static void loadImage(Context context,ImageView view, String url, Float placeholder) { + Glide.with(context).load(url).apply(RequestOptions.bitmapTransform(new GrayscaleTransformation(placeholder))) + .error(R.mipmap.default_image).placeholder(R.mipmap.default_image).diskCacheStrategy(DiskCacheStrategy.ALL).into(view); + } public static void loadIcon(Context context, ImageView view, String url) { if (TextUtils.isEmpty(url)) { diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/utils/ImageUtils.java b/moduleUtil/src/main/java/com/xscm/moduleutil/utils/ImageUtils.java index ace5cd22..d2b969c4 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/utils/ImageUtils.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/utils/ImageUtils.java @@ -194,7 +194,7 @@ public class ImageUtils { return; } } - Glide.with(mImageView).load(path).error(R.mipmap.default_avatar).placeholder(R.mipmap.default_avatar).centerCrop().diskCacheStrategy(DiskCacheStrategy.ALL).into(mImageView); + Glide.with(mImageView).asBitmap().load(path).error(R.mipmap.default_avatar).placeholder(R.mipmap.default_avatar).diskCacheStrategy(DiskCacheStrategy.ALL).into(mImageView); } public static void loadHeadCCTask(String path, ImageView mImageView,int errorImage) { diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/utils/MeHeadView.java b/moduleUtil/src/main/java/com/xscm/moduleutil/utils/MeHeadView.java index c800ca10..753fe749 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/utils/MeHeadView.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/utils/MeHeadView.java @@ -21,6 +21,7 @@ public class MeHeadView extends ConstraintLayout { private AvatarFrameView mIvFrame; private ImageView mIvSex; private ImageView mIvOnline; + private ImageView iv_frame_bg; public MeHeadView(Context context) { this(context, null, 0); @@ -41,10 +42,12 @@ public class MeHeadView extends ConstraintLayout { mIvFrame = findViewById(R.id.iv_frame); mIvSex = findViewById(R.id.iv_sex); mIvOnline = findViewById(R.id.iv_online); + iv_frame_bg=findViewById(R.id.iv_frame_bg); + mIvSex.setVisibility(GONE); } - public void setData(String headPicture, String framePicture, String sex) { - Logger.e(headPicture, framePicture, sex); + public void setData(String headPicture, String framePicture, String nobilityImage) { + Logger.e(headPicture, framePicture, nobilityImage); if (!TextUtils.isEmpty(headPicture)) { ImageUtils.loadHeadCC(headPicture, mRiv); } @@ -55,19 +58,26 @@ public class MeHeadView extends ConstraintLayout { mIvFrame.setVisibility(VISIBLE); mIvFrame.setSource(framePicture, 1); } - if (!TextUtils.isEmpty(sex)) { - mIvSex.setVisibility(VISIBLE); - if (sex.equals("1")){ - mIvSex.setBackgroundResource(R.mipmap.nan); - }else { - mIvSex.setBackgroundResource(R.mipmap.nv); - } - - } else { - mIvSex.setVisibility(GONE); - } +// if (!TextUtils.isEmpty(sex)) { +// mIvSex.setVisibility(GONE); +// if (sex.equals("1")){ +// mIvSex.setBackgroundResource(R.mipmap.nan); +// }else { +// mIvSex.setBackgroundResource(R.mipmap.nv); +// } +// +// } else { +// mIvSex.setVisibility(GONE); +// } // ImageUtils.loadImageView(framePicture, mIvFrame); + if (nobilityImage!=null && !TextUtils.isEmpty(nobilityImage)){ + iv_frame_bg.setVisibility(VISIBLE); + ImageUtils.loadHeadCC(nobilityImage, iv_frame_bg); + }else { + iv_frame_bg.setVisibility(GONE); + } + } public void setOnline(boolean isOnline) { diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/utils/config/EnvironmentEnum.java b/moduleUtil/src/main/java/com/xscm/moduleutil/utils/config/EnvironmentEnum.java index bd1d5f8f..12658158 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/utils/config/EnvironmentEnum.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/utils/config/EnvironmentEnum.java @@ -17,7 +17,7 @@ public enum EnvironmentEnum { "http://1.13.101.98/h5", 0), TEST(//测试环境 - "https://test.vespa.qxyushen.top/", + "http://test.vespa.xscmmidi.site/", "6rdWuz058oq5OahdbFiGEybUcdahd12J83L34Uc7MrPIrxtFG+rXiwDvRcqNvjwbClbbmvMrmxKVkIysFByBsl0Qe9kqd2w8T/nhK5G6eXXlk2V9AjYCieIU+jRnjZBB+Cfechr6rCGJ2aeBARIsXcRPW7wm9WFK9euh5T+v6Pyte68yNaNdcYCll3+U4/uCEog7HygCnMIbAU+kqoPdmn2H+51YOHW+VsnsHd4w1+I3f8Tt0xLIXGM4GWnQueZ5GR46GTWiSYMy8dCIh9SPIMRyC91GosVcfGPMJSdcXqc=", "https://oss-cn-beijing.aliyuncs.com/", "LTAI5tKgrfcFQxH46ZwWYgFW", @@ -28,7 +28,7 @@ public enum EnvironmentEnum { 1600096890, "02f7339ec98947deaeab173599891932", "tcp://1.13.181.248", - "https://test.vespa.qxyushen.top/h5", + "https://test.vespa.xscmmidi.site/h5", 1); private final String serverUrl;//服务器地址 diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/utils/config/EnvironmentPrefs.java b/moduleUtil/src/main/java/com/xscm/moduleutil/utils/config/EnvironmentPrefs.java index 6c124b81..7055c7e4 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/utils/config/EnvironmentPrefs.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/utils/config/EnvironmentPrefs.java @@ -31,11 +31,11 @@ public class EnvironmentPrefs { // 获取当前选择的环境,默认根据构建变体决定 public EnvironmentEnum getSelectedEnvironment() { // 默认使用生产环境 - String envName = sharedPreferences.getString(KEY_ENV, EnvironmentEnum.PRODUCTION.name()); + String envName = sharedPreferences.getString(KEY_ENV, EnvironmentEnum.TEST.name()); try { return EnvironmentEnum.valueOf(envName); } catch (IllegalArgumentException e) { - return EnvironmentEnum.PRODUCTION; // 出错时默认返回生产环境 + return EnvironmentEnum.TEST; // 出错时默认返回生产环境 } } } \ No newline at end of file diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/BaseWheatView.java b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/BaseWheatView.java index 29058a02..e5c210eb 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/BaseWheatView.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/BaseWheatView.java @@ -11,7 +11,10 @@ import android.widget.TextView; import androidx.annotation.DrawableRes; import androidx.constraintlayout.widget.ConstraintLayout; +import com.opensource.svgaplayer.SVGADrawable; import com.opensource.svgaplayer.SVGAImageView; +import com.opensource.svgaplayer.SVGAParser; +import com.opensource.svgaplayer.SVGAVideoEntity; import com.xscm.moduleutil.R; import com.xscm.moduleutil.base.CommonAppContext; import com.xscm.moduleutil.base.RoomRollModel; @@ -39,7 +42,10 @@ import com.xscm.moduleutil.utils.logger.Logger; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; +import org.jetbrains.annotations.NotNull; +import java.net.MalformedURLException; +import java.net.URL; import java.util.Map; public abstract class BaseWheatView extends ConstraintLayout implements IBaseWheat { @@ -148,7 +154,7 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe } } - + private SVGAParser mParser; /** @@ -272,7 +278,34 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe mIvRipple.setVisibility(VISIBLE); mIvRipple.post(() -> { if (!mIvRipple.isAnimating()) { - mIvRipple.startAnimation(); + if (pitBean.getMic_cycle()!=null && !pitBean.getMic_cycle().isEmpty()) { + if (mParser != null) { + mIvRipple.startAnimation(); + } else { + mParser = new SVGAParser(getContext()); + try { + mParser.decodeFromURL(new URL(pitBean.getMic_cycle()), new SVGAParser.ParseCompletion() { + + @Override + public void onError() { + + } + + @Override + public void onComplete(@NotNull SVGAVideoEntity svgaVideoEntity) { + SVGADrawable drawable = new SVGADrawable(svgaVideoEntity); + mIvRipple.setImageDrawable(drawable); + mIvRipple.startAnimation(); + } + }); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + } + }else { + + mIvRipple.startAnimation(); + } CommonAppContext.getInstance().onlineMap.put(pitBean.getUser_id(),1); iv_on_line.setVisibility(GONE); } @@ -295,7 +328,34 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe mIvRipple.setVisibility(VISIBLE); mIvRipple.post(() -> { if (!mIvRipple.isAnimating()) { - mIvRipple.startAnimation(); + if (pitBean.getMic_cycle()!=null && !pitBean.getMic_cycle().isEmpty()) { + if (mParser != null) { + mIvRipple.startAnimation(); + } else { + mParser = new SVGAParser(getContext()); + try { + mParser.decodeFromURL(new URL(pitBean.getMic_cycle()), new SVGAParser.ParseCompletion() { + + @Override + public void onError() { + + } + + @Override + public void onComplete(@NotNull SVGAVideoEntity svgaVideoEntity) { + SVGADrawable drawable = new SVGADrawable(svgaVideoEntity); + mIvRipple.setImageDrawable(drawable); + mIvRipple.startAnimation(); + } + }); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + } + }else { + + mIvRipple.startAnimation(); + } CommonAppContext.getInstance().onlineMap.put(pitBean.getUser_id(),1); iv_on_line.setVisibility(GONE); } @@ -770,30 +830,4 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe return WHEAT_HOST.equals(pitNumber); } -// @Override -// public void onRemoteSoundLevelUpdate(String userId, int volume) { -// if (userId.equals(pitBean.getUser_id())) { -// if (volume == 0) { -// mIvRipple.post(() -> { -// mIvRipple.setVisibility(GONE); -// }); -// } else { -// mIvRipple.post(() -> { -// if (!mIvRipple.isAnimating()) { -// mIvRipple.startAnimation(); -// } -// mIvRipple.setVisibility(VISIBLE); -// }); -// } -// if (pitBean.getUser_id().equals(SpUtil.getUserId()) && closePhone) { -// mIvRipple.post(() -> { -// mIvRipple.setVisibility(GONE); -// }); -// } -// } else if (userId.equals("0")) { -// mIvRipple.post(() -> { -// mIvRipple.setVisibility(GONE); -// }); -// } -// } } diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/Constants.java b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/Constants.java index d755128f..a03ae173 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/Constants.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/Constants.java @@ -239,6 +239,7 @@ public class Constants { public static final String FORGOT_PASSWORD = "/api/Login/forgot_password";//忘记密码 public static final String CLEAR_LOGIN_INFO = "/api/Login/logout";//忘记密码 public static final String CANCEL = "/api/Login/cancel";//注销账号 + public static final String POST_MODIFY_HIDE_STATUS = "/api/UserData/modify_hide_status";//设置隐身进入 public static final String GET_MY_INFO = "/api/User/get_user_info";//点击我的获取个人数据 public static final String GET_USER_HOME = "/api/User/get_user_home";//点击获取个人数据 @@ -407,6 +408,9 @@ public class Constants { public static final String GET_EMOTION = "/api/RoomEmoji/type_list";//表情类型列表 public static final String GET_EMOTION_DEATILS = "/api/RoomEmoji/emoji_list";//表情列表 public static final String GET_TEMP_KEY = "/api/Upload/getTempKeys";//获取上传cos的临时秘钥 + public static final String GET_NOBILITY_DETAIL = "/api/Nobility/get_nobility_detail";//爵位详情 + public static final String GET_NOBILITY_LIST = "/api/Nobility/get_nobility_list";//爵位列表 + public static final String GET_NOBILITY_PRICE = "/api/Nobility/get_nobility_price";//爵位购买价格 diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/DropHomeView.java b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/DropHomeView.java new file mode 100644 index 00000000..3cd18cb1 --- /dev/null +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/DropHomeView.java @@ -0,0 +1,286 @@ +package com.xscm.moduleutil.widget; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ObjectAnimator; +import android.content.Context; +import android.os.Build; +import android.util.AttributeSet; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewAnimationUtils; +import android.view.ViewGroup; +import android.widget.LinearLayout; +import com.blankj.utilcode.util.ScreenUtils; +import com.xscm.moduleutil.utils.BarUtils; + +/** + * com.xscm.moduleutil.widget + * qx 首页首充好礼的悬浮框 + * 2025/11/4 + */ +public class DropHomeView extends LinearLayout { + + private int rightMargin = 0; + private float lastX, lastY; + private int screenWidth; + private int screenHeight; // 添加屏幕高度变量 + + public DropHomeView(Context context) { + super(context); + init(); + } + + public DropHomeView(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public DropHomeView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(); + } + + + void init() { + // 初始化屏幕尺寸 + screenWidth = ScreenUtils.getScreenWidth(); + screenHeight = ScreenUtils.getScreenHeight(); + + post(new Runnable() { + @Override + public void run() { + //设置初始位置 + int sh = ScreenUtils.getScreenHeight(); + int sw = ScreenUtils.getScreenWidth(); +// setBackgroundResource(R.drawable.bg_home_drop_view); + int y = (int) (0.6f * sh) - getHeight();//这是设置展示的纵坐标 + // 确保Y坐标不会超出屏幕范围 + y = Math.max(0, Math.min(y, sh - getHeight())); +// int x = sw - getWidth();//这是靠右边展示的 + int x=20 ;//这里这只一小的数值,就是靠左展示的 + setTranslationX(x); + setTranslationY(y); + } + }); + + updateSize(); + mStatusBarHeight = BarUtils.getStatusBarHeight(); + } + /** + * 更新屏幕尺寸信息 + */ + protected void updateSize() { + ViewGroup viewGroup = (ViewGroup) getParent(); + if (viewGroup != null) { + mScreenWidth = viewGroup.getWidth(); + mScreenHeight = viewGroup.getHeight(); + } else { + // 如果父视图为空,使用屏幕的实际宽度和高度 + mScreenWidth = getResources().getDisplayMetrics().widthPixels; + mScreenHeight = getResources().getDisplayMetrics().heightPixels; + } + } + + boolean starDrap = false; + float X1; + float X2; + float Y1; + float Y2; + // 记录视图初始位置 + private float originalX; + private float originalY; + + @Override + public boolean onInterceptTouchEvent(MotionEvent event) { + if (starDrap) return true; + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + X1 = event.getRawX(); + Y1 = event.getRawY(); + // 记录视图当前位置 + originalX = getTranslationX(); + originalY = getTranslationY(); + break; + + case MotionEvent.ACTION_MOVE: + X2 = event.getRawX(); + Y2 = event.getRawY(); + Action(X1, X2, Y1, Y2); + break; + + + } + return starDrap; + } + + String TAG = "DropHourlView"; + + public boolean Action(float X1, float X2, float Y1, float Y2) { + float ComparedX = X2 - X1;//第二次的X坐标的位置减去第一次X坐标的位置,代表X坐标上的变化情况 + float ComparedY = Y2 - Y1;//同理 + //当X坐标的变化量的绝对值大于Y坐标的变化量的绝对值,以X坐标的变化情况作为判断依据 + //上下左右的判断,都在一条直线上,但手指的操作不可能划直线,所有选择变化量大的方向上的量 + //作为判断依据 + if (Math.abs(ComparedX) > 30 || Math.abs(ComparedY) > 30) { + Log.i(TAG, "Action: 拖动"); + starDrap = true; +// setBackgroundResource(R.drawable.bg_home_drop_view); + return true; + } else { + starDrap = false; + return false; + } + } + private float mOriginalRawX; + private float mOriginalRawY; + private float mOriginalX; + private float mOriginalY; + protected int mScreenWidth; + private int mScreenHeight; + private int mStatusBarHeight; + + private void updateViewPosition(MotionEvent event) { + // 计算新的Y位置 + float desY = mOriginalY + event.getRawY() - mOriginalRawY; + + // 限制Y位置不超出屏幕边界 + if (desY < mStatusBarHeight) { + desY = mStatusBarHeight; + } + if (desY > mScreenHeight - getHeight()) { + desY = mScreenHeight - getHeight(); + } + + // 计算新的X位置 + float desX = mOriginalX + event.getRawX() - mOriginalRawX; + + // 限制X位置不超出屏幕边界 + if (desX < 0) { + desX = 0; + } + if (desX > mScreenWidth - getWidth()) { + desX = mScreenWidth - getWidth(); + } + + // 设置视图的新位置 + setX(desX); + setY(desY); + } + private void changeOriginalTouchParams(MotionEvent event) { + mOriginalX = getX();//getX()相对于控件X坐标的距离 + mOriginalY = getY(); + mOriginalRawX = event.getRawX();//getRawX()指控件在屏幕上的X坐标 + mOriginalRawY = event.getRawY(); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + if (event == null) { + return false; + } + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + changeOriginalTouchParams(event); + updateSize(); // 添加这行确保尺寸是最新的 + // ... 其他现有代码 ... + + break; + case MotionEvent.ACTION_MOVE: + + updateViewPosition(event); // 使用更新后的带边界检查的方法 + +// setBackgroundResource(R.drawable.bg_home_drop_view); + // 使用屏幕绝对坐标计算新位置 +// float newX = originalX + (event.getRawX() - X1); +// float newY = originalY + (event.getRawY() - Y1); +// +// // 限制X和Y坐标在屏幕范围内 +// newX = Math.max(0, Math.min(newX, screenWidth - getWidth())); +// newY = Math.max(0, Math.min(newY, screenHeight - getHeight())); +// +// setTranslationX(newX); +// setTranslationY(newY); +// X2 = event.getRawX(); + break; + case MotionEvent.ACTION_UP: + starDrap = false; + int sw = ScreenUtils.getScreenWidth(); + Log.i(TAG, "onTouchEvent: " + sw + "," + X2); + boolean isR = getTranslationX() + getWidth() / 2 >= sw / 2;//贴边方向 + + // 获取当前Y坐标 + float currentY = getTranslationY(); + + // 创建X轴和Y轴的动画 + ObjectAnimator animX = ObjectAnimator.ofFloat(this, "translationX", isR ? sw - getWidth() : 0f).setDuration(200); + // Y轴保持当前位置,但确保在屏幕范围内 + currentY = Math.max(0, Math.min(currentY, screenHeight - getHeight())); + ObjectAnimator animY = ObjectAnimator.ofFloat(this, "translationY", currentY).setDuration(200); + + animX.start(); + animY.start(); + + break; + + } + + return true; + } + + + public void doRevealAnimation(View mPuppet, boolean flag) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + int[] vLocation = new int[2]; + getLocationInWindow(vLocation); + int centerX = vLocation[0] + getMeasuredWidth() / 2; + int centerY = vLocation[1] + getMeasuredHeight() / 2; + + int height = ScreenUtils.getScreenHeight(); + int width = ScreenUtils.getScreenWidth(); + int maxRradius = (int) Math.hypot(height, width); + Log.e("hei", maxRradius + ""); + + if (flag) { + mPuppet.setVisibility(VISIBLE); + Animator animator = ViewAnimationUtils.createCircularReveal(mPuppet, centerX, centerY, maxRradius, 0); + animator.setDuration(600); + animator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + super.onAnimationEnd(animation); + mPuppet.setVisibility(View.GONE); + } + }); + animator.start(); + flag = false; + } else { + Animator animator = ViewAnimationUtils.createCircularReveal(mPuppet, centerX, centerY, 0, maxRradius); + animator.setDuration(1000); + animator.addListener(new Animator.AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + mPuppet.setVisibility(View.VISIBLE); + } + + @Override + public void onAnimationEnd(Animator animation) { + } + + @Override + public void onAnimationCancel(Animator animation) { + + } + + @Override + public void onAnimationRepeat(Animator animation) { + + } + }); + animator.start(); + flag = true; + } + } + } +} diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/GradientTextView.java b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/GradientTextView.java new file mode 100644 index 00000000..50300721 --- /dev/null +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/GradientTextView.java @@ -0,0 +1,51 @@ +package com.xscm.moduleutil.widget; + +import android.content.Context; +import android.graphics.LinearGradient; +import android.graphics.Shader; +import android.util.AttributeSet; +import androidx.appcompat.widget.AppCompatTextView; + +/** + * com.xscm.moduleutil.widget + * qx 爵位中的文字渐变颜色 + * 2025/11/8 + */ +public class GradientTextView extends AppCompatTextView { + + public GradientTextView(Context context) { + super(context); + } + + public GradientTextView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public GradientTextView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + super.onLayout(changed, left, top, right, bottom); + if (changed) { + createGradient(); + } + } + + private void createGradient() { + // 获取TextView的宽度 + int width = getWidth(); + if (width > 0) { + // 创建从左到右的线性渐变 #A292FF -> #FFFFFF -> #A292FF + LinearGradient gradient = new LinearGradient( + 0, 0, width, 0, + new int[]{0xFFA292FF, 0xFFFFFFFF, 0xFFA292FF}, + new float[]{0f, 0.5f, 1f}, + Shader.TileMode.CLAMP + ); + getPaint().setShader(gradient); + invalidate(); + } + } +} diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/RoomSingSongWheatView.java b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/RoomSingSongWheatView.java index 74882384..26d7661b 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/RoomSingSongWheatView.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/RoomSingSongWheatView.java @@ -8,11 +8,18 @@ import android.view.View; import android.widget.ImageView; import android.widget.TextView; +import com.opensource.svgaplayer.SVGADrawable; +import com.opensource.svgaplayer.SVGAParser; +import com.opensource.svgaplayer.SVGAVideoEntity; import com.xscm.moduleutil.R; import com.xscm.moduleutil.bean.UserInfo; import com.xscm.moduleutil.bean.room.RoomPitBean; import com.xscm.moduleutil.utils.ImageUtils; import com.xscm.moduleutil.utils.SpUtil; +import org.jetbrains.annotations.NotNull; + +import java.net.MalformedURLException; +import java.net.URL; /** * @Author lxj$ @@ -81,6 +88,7 @@ public class RoomSingSongWheatView extends BaseWheatView { private void handleOnState(RoomPitBean bean) { mIvRipple.setVisibility(VISIBLE); + mTvName.setText(bean.getNickname()); ImageUtils.loadHeadCC(bean.getAvatar(), mRiv); mCharmView.setVisibility(VISIBLE); @@ -285,6 +293,7 @@ public class RoomSingSongWheatView extends BaseWheatView { // 暂无实现 } + private SVGAParser mParser; @Override public void onLocalSoundLevelUpdate(int volume) { if (mIvRipple == null) { @@ -301,9 +310,33 @@ public class RoomSingSongWheatView extends BaseWheatView { } else { mIvRipple.post(() -> { mIvRipple.setVisibility(VISIBLE); - mIvRipple.startAnimation(); + if (pitBean.getMic_cycle()!=null && !pitBean.getMic_cycle().isEmpty()) { + if (mParser != null) { + mIvRipple.startAnimation(); + } else { + mParser = new SVGAParser(getContext()); + try { + mParser.decodeFromURL(new URL(pitBean.getMic_cycle()), new SVGAParser.ParseCompletion() { + @Override + public void onError() { + + } + + @Override + public void onComplete(@NotNull SVGAVideoEntity svgaVideoEntity) { + SVGADrawable drawable = new SVGADrawable(svgaVideoEntity); + mIvRipple.setImageDrawable(drawable); + mIvRipple.startAnimation(); + } + }); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + } + } }); + } } } diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/WheatLayoutManager.java b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/WheatLayoutManager.java index 86c8a582..8b2ad260 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/WheatLayoutManager.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/WheatLayoutManager.java @@ -288,7 +288,7 @@ public class WheatLayoutManager { }else if (layoutType==1){ wheatView.setTv_time_pk(true); } - wheatView.setSex(bean.getCharm(),true); + wheatView.setSex(bean.getCharm(),false); } } diff --git a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/WheatLayoutSingManager.java b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/WheatLayoutSingManager.java index 64bd69d0..c3ae3600 100644 --- a/moduleUtil/src/main/java/com/xscm/moduleutil/widget/WheatLayoutSingManager.java +++ b/moduleUtil/src/main/java/com/xscm/moduleutil/widget/WheatLayoutSingManager.java @@ -167,7 +167,7 @@ public class WheatLayoutSingManager { wheatView.setLayoutParams(params); - GifAvatarOvalView avatarView = (GifAvatarOvalView) wheatView.mRiv; + CircularImage avatarView = (CircularImage) wheatView.mRiv; avatarView.setOnClickListener(v -> { if (wheatClickListener != null) { wheatClickListener.onWheatClick(wheatView, pitNumber); @@ -391,6 +391,7 @@ public class WheatLayoutSingManager { bean.setSex(""); bean.setUser_code(""); bean.setDress_picture(""); + bean.setMic_cycle(""); view.setData(bean); } } diff --git a/moduleUtil/src/main/res/drawable/bg_me_gift_wall.xml b/moduleUtil/src/main/res/drawable/bg_me_gift_wall.xml new file mode 100644 index 00000000..6fbb7778 --- /dev/null +++ b/moduleUtil/src/main/res/drawable/bg_me_gift_wall.xml @@ -0,0 +1,13 @@ + + + + + \ No newline at end of file diff --git a/moduleUtil/src/main/res/drawable/bg_me_wallet.xml b/moduleUtil/src/main/res/drawable/bg_me_wallet.xml new file mode 100644 index 00000000..beacd10a --- /dev/null +++ b/moduleUtil/src/main/res/drawable/bg_me_wallet.xml @@ -0,0 +1,15 @@ + + + + + \ No newline at end of file diff --git a/moduleUtil/src/main/res/drawable/bg_r4_2a2925.xml b/moduleUtil/src/main/res/drawable/bg_r4_2a2925.xml new file mode 100644 index 00000000..44b1465f --- /dev/null +++ b/moduleUtil/src/main/res/drawable/bg_r4_2a2925.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/moduleUtil/src/main/res/drawable/bg_r6_2a2a4e.xml b/moduleUtil/src/main/res/drawable/bg_r6_2a2a4e.xml new file mode 100644 index 00000000..d9083609 --- /dev/null +++ b/moduleUtil/src/main/res/drawable/bg_r6_2a2a4e.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/moduleUtil/src/main/res/drawable/bg_r8_f8f6c7_fffff.xml b/moduleUtil/src/main/res/drawable/bg_r8_f8f6c7_fffff.xml new file mode 100644 index 00000000..59e0b382 --- /dev/null +++ b/moduleUtil/src/main/res/drawable/bg_r8_f8f6c7_fffff.xml @@ -0,0 +1,15 @@ + + + + + \ No newline at end of file diff --git a/moduleUtil/src/main/res/drawable/tab_indicator_bg.xml b/moduleUtil/src/main/res/drawable/tab_indicator_bg.xml new file mode 100644 index 00000000..838e6693 --- /dev/null +++ b/moduleUtil/src/main/res/drawable/tab_indicator_bg.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/moduleUtil/src/main/res/drawable/tab_indicator_bottom.xml b/moduleUtil/src/main/res/drawable/tab_indicator_bottom.xml new file mode 100644 index 00000000..8fc54119 --- /dev/null +++ b/moduleUtil/src/main/res/drawable/tab_indicator_bottom.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/moduleUtil/src/main/res/layout/ease_row_received_message_user_send.xml b/moduleUtil/src/main/res/layout/ease_row_received_message_user_send.xml index 494ae777..9a8b65c9 100644 --- a/moduleUtil/src/main/res/layout/ease_row_received_message_user_send.xml +++ b/moduleUtil/src/main/res/layout/ease_row_received_message_user_send.xml @@ -24,10 +24,10 @@ - + + diff --git a/moduleUtil/src/main/res/layout/me_view_decoration_head.xml b/moduleUtil/src/main/res/layout/me_view_decoration_head.xml index 62fd9026..e786c376 100644 --- a/moduleUtil/src/main/res/layout/me_view_decoration_head.xml +++ b/moduleUtil/src/main/res/layout/me_view_decoration_head.xml @@ -1,58 +1,80 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:clipChildren="false" + android:clipToPadding="false" + xmlns:tools="http://schemas.android.com/tools"> + android:id="@+id/riv" + android:layout_width="0dp" + android:layout_height="0dp" + android:background="@drawable/me_avatar_bg" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintDimensionRatio="1:1" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintWidth_percent="0.90154" + android:src="@mipmap/default_avatar" + app:riv_oval="true"/> + android:id="@+id/iv_sex" + android:layout_width="@dimen/dp_16" + android:layout_height="@dimen/dp_16" + android:background="@mipmap/nan" + android:visibility="gone" + tools:visibility="visible" + app:layout_constraintBottom_toBottomOf="@id/riv" + app:layout_constraintEnd_toEndOf="@id/riv" + /> + android:id="@+id/iv_frame" + android:layout_width="0dp" + android:layout_height="0dp" + android:contentDescription="@null" + android:scaleType="fitXY" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintDimensionRatio="1:1" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"/> + + + android:id="@+id/iv_frame_bg" + android:layout_width="match_parent" + android:layout_height="0dp" + android:contentDescription="@null" + android:scaleType="fitXY" + tools:src="@mipmap/me_sj" + app:layout_constraintTop_toTopOf="@+id/guideline" + app:layout_constraintWidth_default="spread" + app:layout_constraintHeight_default="spread" + /> + + \ No newline at end of file diff --git a/moduleUtil/src/main/res/layout/room_view_default_wheat.xml b/moduleUtil/src/main/res/layout/room_view_default_wheat.xml index f33151ff..c4581290 100644 --- a/moduleUtil/src/main/res/layout/room_view_default_wheat.xml +++ b/moduleUtil/src/main/res/layout/room_view_default_wheat.xml @@ -1,103 +1,103 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools"> + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:clipChildren="false" + android:clipToPadding="false"> + android:id="@+id/riv" + android:layout_width="0dp" + android:layout_height="0dp" + android:layout_marginStart="@dimen/dp_12" + android:layout_marginTop="@dimen/dp_12" + android:layout_marginEnd="@dimen/dp_12" + android:adjustViewBounds="true" + android:scaleType="fitCenter" + android:src="@mipmap/room_ic_wheat_default" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintDimensionRatio="1:1" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"/> + android:id="@+id/iv_ripple" + android:layout_width="0dp" + android:layout_height="0dp" + android:layout_marginTop="@dimen/dp_8" + app:autoPlay="false" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintDimensionRatio="1:1.05" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:loopCount="0" + app:source="mic.svga"/> - - - - - - - - - - - - + + + + + + + + + + + + + android:id="@+id/iv_sex" + android:layout_width="0dp" + android:layout_height="0dp" + android:background="@mipmap/common_ic_headportriat_base" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="@id/riv" + app:layout_constraintEnd_toEndOf="@id/riv" + app:layout_constraintStart_toStartOf="@id/riv" + app:layout_constraintTop_toTopOf="@id/riv" + tools:visibility="visible"/> + android:id="@+id/view2" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="15dp" + android:visibility="gone" + app:layout_constraintEnd_toEndOf="@id/riv" + app:layout_constraintStart_toStartOf="@id/riv" + app:layout_constraintTop_toTopOf="@id/riv"/> + android:id="@+id/iv_tag_boos" + android:layout_width="32dp" + android:layout_height="14dp" + android:src="@mipmap/room_ic_wheat_tag_boss" + android:visibility="gone" + app:layout_constraintBottom_toTopOf="@id/view2" + app:layout_constraintEnd_toEndOf="@id/riv" + app:layout_constraintStart_toStartOf="@id/riv" + tools:visibility="visible"/> + android:id="@+id/iv_tag_type" + android:layout_width="@dimen/dp_30" + android:layout_height="@dimen/dp_20" + android:layout_marginTop="@dimen/dp_5" + android:src="@mipmap/zc" + app:layout_constraintBottom_toBottomOf="@id/riv" + app:layout_constraintEnd_toEndOf="@id/riv" + app:layout_constraintStart_toStartOf="@id/riv"/> @@ -116,179 +116,178 @@ + android:id="@+id/tv_time" + android:layout_width="@dimen/dp_35" + android:layout_height="17.5dp" + android:background="@mipmap/za_s" + android:gravity="center" + android:text="00:00" + android:textColor="@color/white" + android:textSize="@dimen/sp_9" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="@id/riv" + app:layout_constraintEnd_toEndOf="@id/riv" + app:layout_constraintStart_toStartOf="@id/riv" + tools:visibility="visible"/> + android:id="@+id/iv_frame" + android:layout_width="0dp" + android:layout_height="0dp" + android:layout_marginStart="@dimen/dp_12" + android:layout_marginTop="@dimen/dp_12" + android:layout_marginEnd="@dimen/dp_12" + android:adjustViewBounds="true" + android:scaleType="fitCenter" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintDimensionRatio="1:1" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"/> + android:id="@+id/view_riv_bottom" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginBottom="7dp" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="@id/riv" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent"/> + android:id="@+id/cl_guide1" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical" + app:layout_constraintGuide_percent="0.2"/> + android:id="@+id/tv_name" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:gravity="center" + android:paddingLeft="@dimen/dp_5" + android:paddingRight="@dimen/dp_5" + android:singleLine="true" + android:layout_marginTop="@dimen/dp_3" + android:textColor="@color/white" + android:textSize="@dimen/sp_10" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/riv" + tools:text="麦位1" + tools:textColor="@color/color_FF333333"/> + android:id="@+id/charm_view" + android:layout_width="@dimen/dp_52" + android:layout_height="@dimen/dp_12" + android:layout_marginBottom="@dimen/dp_5" + android:clipChildren="false" + android:clipToPadding="false" + android:visibility="visible" + app:layout_constraintEnd_toEndOf="@id/riv" + app:layout_constraintStart_toStartOf="@id/riv" + app:layout_constraintTop_toBottomOf="@id/tv_name"/> + android:id="@+id/tv_time_pk" + android:layout_width="@dimen/dp_35" + android:layout_height="17.5dp" + android:background="@mipmap/za_s" + android:layout_marginBottom="@dimen/dp_5" + android:gravity="center" + android:text="00:00" + android:textColor="@color/white" + android:textSize="@dimen/sp_9" + android:visibility="gone" + app:layout_constraintEnd_toEndOf="@id/riv" + app:layout_constraintStart_toStartOf="@id/riv" + app:layout_constraintTop_toBottomOf="@id/tv_name" + tools:visibility="visible"/> + android:id="@+id/iv_shutup" + android:layout_width="0dp" + android:layout_height="0dp" + android:layout_marginRight="5dp" + android:layout_marginBottom="4dp" + android:src="@mipmap/room_ic_wheat_shutup" + android:visibility="invisible" + app:layout_constraintBottom_toBottomOf="@id/riv" + app:layout_constraintHeight_percent="0.05" + app:layout_constraintStart_toStartOf="@id/riv" + app:layout_constraintWidth_percent="0.05" + tools:visibility="visible"/> + android:id="@+id/iv_online" + android:layout_width="0dp" + android:layout_height="0dp" + android:adjustViewBounds="true" + android:scaleType="fitXY" + android:visibility="gone" + android:src="@mipmap/room_ic_owner_offline" + app:layout_constraintBottom_toBottomOf="@+id/riv" + app:layout_constraintEnd_toEndOf="@+id/riv" + app:layout_constraintStart_toStartOf="@+id/riv" + app:layout_constraintTop_toTopOf="@+id/riv" + tools:visibility="visible"/> + android:id="@+id/iv_face" + android:layout_width="0dp" + android:layout_height="0dp" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="@id/riv" + app:layout_constraintEnd_toEndOf="@id/riv" + app:layout_constraintHorizontal_bias="1.0" + app:layout_constraintStart_toStartOf="@id/riv" + app:layout_constraintTop_toTopOf="@id/riv" + app:layout_constraintVertical_bias="0.0"/> + android:id="@+id/iv_gift" + android:layout_width="0dp" + android:layout_height="0dp" + android:visibility="visible" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintDimensionRatio="1:0.6" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHeight_percent="0.7" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"/> + android:id="@+id/iv_maozi" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginLeft="@dimen/dp_10" + android:layout_marginTop="@dimen/dp_1" + android:scaleType="centerInside" + android:src="@mipmap/ic_room_huangguan" + android:visibility="gone" + app:layout_constraintStart_toStartOf="@id/iv_frame" + app:layout_constraintTop_toTopOf="@id/iv_frame" + tools:visibility="visible"/> + android:id="@+id/tv_no" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:background="@mipmap/ic_room_xq_wno_male" + android:gravity="center" + android:text="1" + android:textColor="#fff" + android:textSize="@dimen/sp_10" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="@id/iv_frame" + app:layout_constraintEnd_toEndOf="@id/riv" + app:layout_constraintStart_toStartOf="@id/riv" + tools:visibility="visible"/> diff --git a/moduleUtil/src/main/res/layout/room_view_friendship_wheat.xml b/moduleUtil/src/main/res/layout/room_view_friendship_wheat.xml index dcbfa456..0181a088 100644 --- a/moduleUtil/src/main/res/layout/room_view_friendship_wheat.xml +++ b/moduleUtil/src/main/res/layout/room_view_friendship_wheat.xml @@ -53,7 +53,7 @@ app:layout_constraintStart_toStartOf="@id/iv_frame" app:layout_constraintTop_toTopOf="@id/iv_frame" app:loopCount="0" - app:source="ripple3695.svga" /> + app:source="mic.svga" /> diff --git a/moduleUtil/src/main/res/layout/room_view_ktv_wheat.xml b/moduleUtil/src/main/res/layout/room_view_ktv_wheat.xml index 7d5f21ba..435a835c 100644 --- a/moduleUtil/src/main/res/layout/room_view_ktv_wheat.xml +++ b/moduleUtil/src/main/res/layout/room_view_ktv_wheat.xml @@ -77,7 +77,7 @@ app:layout_constraintHeight_default="percent" app:layout_constraintHeight_percent="0.52" app:loopCount="0" - app:source="ripple3695.svga" /> + app:source="mic.svga" /> diff --git a/moduleUtil/src/main/res/layout/room_view_make_wheat.xml b/moduleUtil/src/main/res/layout/room_view_make_wheat.xml index 32c93329..712cd0f7 100644 --- a/moduleUtil/src/main/res/layout/room_view_make_wheat.xml +++ b/moduleUtil/src/main/res/layout/room_view_make_wheat.xml @@ -55,7 +55,7 @@ app:layout_constraintTop_toTopOf="parent" app:layout_constraintWidth_percent="0.8" app:loopCount="0" - app:source="ripple3695.svga" + app:source="mic.svga" tools:visibility="visible" /> diff --git a/moduleUtil/src/main/res/layout/room_view_sing_wheat.xml b/moduleUtil/src/main/res/layout/room_view_sing_wheat.xml index 193eab7a..32f6c81a 100644 --- a/moduleUtil/src/main/res/layout/room_view_sing_wheat.xml +++ b/moduleUtil/src/main/res/layout/room_view_sing_wheat.xml @@ -1,7 +1,7 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools"> @@ -13,38 +13,38 @@ android:clipChildren="false" android:clipToPadding="false"> - + + android:id="@+id/iv_frame" + android:layout_width="0dp" + android:layout_height="0dp" + android:adjustViewBounds="true" + android:scaleType="fitCenter" + android:visibility="gone" + tools:visibility="visible" + android:layout_marginTop="@dimen/dp_10" + app:layout_constraintHeight_percent="0.9" + app:layout_constraintWidth_percent="0.8" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"/> + app:source="mic.svga" /> + android:id="@+id/iv_sex" + android:layout_width="0dp" + android:layout_height="0dp" + android:background="@mipmap/common_ic_headportriat_base" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="@id/riv" + app:layout_constraintEnd_toEndOf="@id/riv" + app:layout_constraintStart_toStartOf="@id/riv" + app:layout_constraintTop_toTopOf="@id/riv" + tools:visibility="visible" /> + android:id="@+id/view2" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="15dp" + android:visibility="gone" + app:layout_constraintEnd_toEndOf="@id/riv" + app:layout_constraintStart_toStartOf="@id/riv" + app:layout_constraintTop_toTopOf="@id/riv" /> + android:id="@+id/iv_tag_boos" + android:layout_width="32dp" + android:layout_height="14dp" + android:src="@mipmap/room_ic_wheat_tag_boss" + android:visibility="gone" + app:layout_constraintBottom_toTopOf="@id/view2" + app:layout_constraintEnd_toEndOf="@id/riv" + app:layout_constraintStart_toStartOf="@id/riv" + tools:visibility="visible" /> + android:id="@+id/iv_tag_type" + android:layout_width="@dimen/dp_30" + android:layout_height="@dimen/dp_20" + android:layout_marginTop="@dimen/dp_5" + android:src="@mipmap/zc" + app:layout_constraintBottom_toBottomOf="@id/riv" + app:layout_constraintEnd_toEndOf="@id/riv" + app:layout_constraintStart_toStartOf="@id/riv" /> - - - - - - - - - - - - - - - + android:id="@+id/tv_time" + android:layout_width="@dimen/dp_35" + android:layout_height="17.5dp" + android:background="@mipmap/za_s" + android:gravity="center" + android:text="00:00" + android:textColor="@color/white" + android:textSize="@dimen/sp_9" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="@id/riv" + app:layout_constraintEnd_toEndOf="@id/riv" + app:layout_constraintStart_toStartOf="@id/riv" + tools:visibility="visible" /> + android:id="@+id/view_riv_bottom" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginBottom="7dp" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="@id/riv" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" /> + android:id="@+id/cl_guide1" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical" + app:layout_constraintGuide_percent="0.2" /> + android:id="@+id/tv_name" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:gravity="center" + android:paddingLeft="@dimen/dp_5" + android:paddingRight="@dimen/dp_5" + android:singleLine="true" + android:layout_marginTop="@dimen/dp_6" + android:textColor="@color/white" + android:translationZ="@dimen/dp_10" + android:textSize="@dimen/sp_10" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/riv" + tools:text="麦位1" + tools:textColor="@color/color_FF333333" /> + android:id="@+id/charm_view" + android:layout_width="@dimen/dp_52" + android:layout_height="@dimen/dp_12" + android:layout_marginBottom="@dimen/dp_5" + android:clipChildren="false" + android:clipToPadding="false" + android:visibility="visible" + app:layout_constraintEnd_toEndOf="@id/riv" + app:layout_constraintStart_toStartOf="@id/riv" + app:layout_constraintTop_toBottomOf="@id/tv_name" /> + android:id="@+id/tv_time_pk" + android:layout_width="@dimen/dp_35" + android:layout_height="17.5dp" + android:background="@mipmap/za_s" + android:layout_marginBottom="@dimen/dp_5" + android:gravity="center" + android:text="00:00" + android:textColor="@color/white" + android:textSize="@dimen/sp_9" + android:visibility="gone" + app:layout_constraintEnd_toEndOf="@id/riv" + app:layout_constraintStart_toStartOf="@id/riv" + app:layout_constraintTop_toBottomOf="@id/tv_name" + tools:visibility="visible" /> + android:id="@+id/iv_shutup" + android:layout_width="0dp" + android:layout_height="0dp" + android:layout_marginRight="5dp" + android:layout_marginBottom="4dp" + android:src="@mipmap/room_ic_wheat_shutup" + android:visibility="invisible" + app:layout_constraintBottom_toBottomOf="@id/riv" + app:layout_constraintHeight_percent="0.05" + app:layout_constraintStart_toStartOf="@id/riv" + app:layout_constraintWidth_percent="0.05" + tools:visibility="visible" /> + android:id="@+id/iv_online" + android:layout_width="0dp" + android:layout_height="0dp" + android:background="@mipmap/room_ic_owner_offline" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintDimensionRatio="1:1" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHeight_percent="0.82" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + android:layout_marginTop="@dimen/dp_10" + app:loopCount="0" + tools:visibility="visible" /> + android:id="@+id/iv_face" + android:layout_width="0dp" + android:layout_height="0dp" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="@id/riv" + app:layout_constraintEnd_toEndOf="@id/riv" + app:layout_constraintHorizontal_bias="1.0" + app:layout_constraintStart_toStartOf="@id/riv" + app:layout_constraintTop_toTopOf="@id/riv" + app:layout_constraintVertical_bias="0.0" /> + android:id="@+id/iv_gift" + android:layout_width="0dp" + android:layout_height="0dp" + android:visibility="visible" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintDimensionRatio="1:0.6" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHeight_percent="0.7" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + android:id="@+id/iv_maozi" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginLeft="@dimen/dp_10" + android:layout_marginTop="@dimen/dp_1" + android:scaleType="centerInside" + android:src="@mipmap/ic_room_huangguan" + android:visibility="gone" + app:layout_constraintStart_toStartOf="@id/iv_frame" + app:layout_constraintTop_toTopOf="@id/iv_frame" + tools:visibility="visible" /> + android:id="@+id/tv_no" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:background="@mipmap/ic_room_xq_wno_male" + android:gravity="center" + android:text="1" + android:textColor="#fff" + android:textSize="@dimen/sp_10" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="@id/iv_frame" + app:layout_constraintEnd_toEndOf="@id/riv" + app:layout_constraintStart_toStartOf="@id/riv" + tools:visibility="visible" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/moduleUtil/src/main/res/mipmap-hdpi/arrow_right.png b/moduleUtil/src/main/res/mipmap-hdpi/arrow_right.png new file mode 100644 index 00000000..38145f98 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/arrow_right.png differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/beautiful.webp b/moduleUtil/src/main/res/mipmap-hdpi/beautiful.webp new file mode 100644 index 00000000..a6c88578 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/beautiful.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/cp_tx_k.png b/moduleUtil/src/main/res/mipmap-hdpi/cp_tx_k.png deleted file mode 100644 index 85e5f003..00000000 Binary files a/moduleUtil/src/main/res/mipmap-hdpi/cp_tx_k.png and /dev/null differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/cp_tx_k.webp b/moduleUtil/src/main/res/mipmap-hdpi/cp_tx_k.webp new file mode 100644 index 00000000..596d5af1 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/cp_tx_k.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/gift_wall_liang.webp b/moduleUtil/src/main/res/mipmap-hdpi/gift_wall_liang.webp new file mode 100644 index 00000000..d86b1cc0 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/gift_wall_liang.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/gift_wall_no_liang.webp b/moduleUtil/src/main/res/mipmap-hdpi/gift_wall_no_liang.webp new file mode 100644 index 00000000..1c2dca96 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/gift_wall_no_liang.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/icon_no.webp b/moduleUtil/src/main/res/mipmap-hdpi/icon_no.webp new file mode 100644 index 00000000..a376eab0 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/icon_no.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/icon_noble_d.webp b/moduleUtil/src/main/res/mipmap-hdpi/icon_noble_d.webp new file mode 100644 index 00000000..5a91198b Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/icon_noble_d.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/icon_noble_gz.webp b/moduleUtil/src/main/res/mipmap-hdpi/icon_noble_gz.webp new file mode 100644 index 00000000..d393aa18 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/icon_noble_gz.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/icon_noble_title.webp b/moduleUtil/src/main/res/mipmap-hdpi/icon_noble_title.webp new file mode 100644 index 00000000..d337505f Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/icon_noble_title.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/icon_yes.webp b/moduleUtil/src/main/res/mipmap-hdpi/icon_yes.webp new file mode 100644 index 00000000..0bfacc94 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/icon_yes.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/me_edit.webp b/moduleUtil/src/main/res/mipmap-hdpi/me_edit.webp new file mode 100644 index 00000000..39b17634 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/me_edit.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/me_gh.webp b/moduleUtil/src/main/res/mipmap-hdpi/me_gh.webp new file mode 100644 index 00000000..5a629971 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/me_gh.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/me_help.webp b/moduleUtil/src/main/res/mipmap-hdpi/me_help.webp new file mode 100644 index 00000000..4b53cc86 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/me_help.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/me_home.webp b/moduleUtil/src/main/res/mipmap-hdpi/me_home.webp new file mode 100644 index 00000000..9f65d24f Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/me_home.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/me_income.webp b/moduleUtil/src/main/res/mipmap-hdpi/me_income.webp new file mode 100644 index 00000000..f55eddc6 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/me_income.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/me_invitation.webp b/moduleUtil/src/main/res/mipmap-hdpi/me_invitation.webp new file mode 100644 index 00000000..4250f001 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/me_invitation.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/me_my_bag.webp b/moduleUtil/src/main/res/mipmap-hdpi/me_my_bag.webp new file mode 100644 index 00000000..65ee9e33 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/me_my_bag.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/me_noble_bj.webp b/moduleUtil/src/main/res/mipmap-hdpi/me_noble_bj.webp new file mode 100644 index 00000000..a7fe0935 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/me_noble_bj.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/me_noble_image.webp b/moduleUtil/src/main/res/mipmap-hdpi/me_noble_image.webp new file mode 100644 index 00000000..1ea63de0 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/me_noble_image.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/me_noble_no.webp b/moduleUtil/src/main/res/mipmap-hdpi/me_noble_no.webp new file mode 100644 index 00000000..4e978503 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/me_noble_no.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/me_noble_xf.webp b/moduleUtil/src/main/res/mipmap-hdpi/me_noble_xf.webp new file mode 100644 index 00000000..a730c0db Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/me_noble_xf.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/me_opinion.webp b/moduleUtil/src/main/res/mipmap-hdpi/me_opinion.webp new file mode 100644 index 00000000..1577d3d8 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/me_opinion.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/me_recharge.webp b/moduleUtil/src/main/res/mipmap-hdpi/me_recharge.webp new file mode 100644 index 00000000..f3f62840 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/me_recharge.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/me_setting.webp b/moduleUtil/src/main/res/mipmap-hdpi/me_setting.webp new file mode 100644 index 00000000..12620841 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/me_setting.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/me_show_store.webp b/moduleUtil/src/main/res/mipmap-hdpi/me_show_store.webp new file mode 100644 index 00000000..c28992e7 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/me_show_store.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/me_sj.webp b/moduleUtil/src/main/res/mipmap-hdpi/me_sj.webp new file mode 100644 index 00000000..4b7cf38e Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/me_sj.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/me_test.webp b/moduleUtil/src/main/res/mipmap-hdpi/me_test.webp new file mode 100644 index 00000000..53f24612 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/me_test.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/me_zy.webp b/moduleUtil/src/main/res/mipmap-hdpi/me_zy.webp new file mode 100644 index 00000000..afc7c801 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/me_zy.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/my_dan.webp b/moduleUtil/src/main/res/mipmap-hdpi/my_dan.webp new file mode 100644 index 00000000..54113872 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/my_dan.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/my_noblesse.webp b/moduleUtil/src/main/res/mipmap-hdpi/my_noblesse.webp new file mode 100644 index 00000000..e503e773 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/my_noblesse.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/noble_cz_ts.webp b/moduleUtil/src/main/res/mipmap-hdpi/noble_cz_ts.webp new file mode 100644 index 00000000..f5692f0b Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/noble_cz_ts.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/noble_details_bj.webp b/moduleUtil/src/main/res/mipmap-hdpi/noble_details_bj.webp new file mode 100644 index 00000000..2ae6a7c6 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/noble_details_bj.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/noble_details_tq.webp b/moduleUtil/src/main/res/mipmap-hdpi/noble_details_tq.webp new file mode 100644 index 00000000..b876a100 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/noble_details_tq.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/noble_duib.webp b/moduleUtil/src/main/res/mipmap-hdpi/noble_duib.webp new file mode 100644 index 00000000..f7744da0 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/noble_duib.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/noble_h_kt.webp b/moduleUtil/src/main/res/mipmap-hdpi/noble_h_kt.webp new file mode 100644 index 00000000..06992e4f Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/noble_h_kt.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/noble_is_lock.webp b/moduleUtil/src/main/res/mipmap-hdpi/noble_is_lock.webp new file mode 100644 index 00000000..b2a980fb Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/noble_is_lock.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/noble_kt.webp b/moduleUtil/src/main/res/mipmap-hdpi/noble_kt.webp new file mode 100644 index 00000000..28131ef8 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/noble_kt.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/noble_ljkt.webp b/moduleUtil/src/main/res/mipmap-hdpi/noble_ljkt.webp new file mode 100644 index 00000000..99a7fd60 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/noble_ljkt.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/noble_ljsj.webp b/moduleUtil/src/main/res/mipmap-hdpi/noble_ljsj.webp new file mode 100644 index 00000000..120d89f7 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/noble_ljsj.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/noble_seccer.webp b/moduleUtil/src/main/res/mipmap-hdpi/noble_seccer.webp new file mode 100644 index 00000000..d6eeee7b Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/noble_seccer.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/noble_sj.webp b/moduleUtil/src/main/res/mipmap-hdpi/noble_sj.webp new file mode 100644 index 00000000..44bc6cf4 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/noble_sj.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/noble_xf.webp b/moduleUtil/src/main/res/mipmap-hdpi/noble_xf.webp new file mode 100644 index 00000000..b67c3886 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/noble_xf.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/noble_yxq.webp b/moduleUtil/src/main/res/mipmap-hdpi/noble_yxq.webp new file mode 100644 index 00000000..0c235e87 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/noble_yxq.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/noble_zf_bj.webp b/moduleUtil/src/main/res/mipmap-hdpi/noble_zf_bj.webp new file mode 100644 index 00000000..29e905d4 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/noble_zf_bj.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/personality.webp b/moduleUtil/src/main/res/mipmap-hdpi/personality.webp new file mode 100644 index 00000000..6c2b1bae Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/personality.webp differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/ranking_user_cp_k.png b/moduleUtil/src/main/res/mipmap-hdpi/ranking_user_cp_k.png deleted file mode 100644 index 03abeb87..00000000 Binary files a/moduleUtil/src/main/res/mipmap-hdpi/ranking_user_cp_k.png and /dev/null differ diff --git a/moduleUtil/src/main/res/mipmap-hdpi/ranking_user_cp_k.webp b/moduleUtil/src/main/res/mipmap-hdpi/ranking_user_cp_k.webp new file mode 100644 index 00000000..2d2e9e71 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-hdpi/ranking_user_cp_k.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/arrow_right.png b/moduleUtil/src/main/res/mipmap-xhdpi/arrow_right.png new file mode 100644 index 00000000..bab79b97 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/arrow_right.png differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/beautiful.webp b/moduleUtil/src/main/res/mipmap-xhdpi/beautiful.webp new file mode 100644 index 00000000..85546856 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/beautiful.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/cp_tx_k.png b/moduleUtil/src/main/res/mipmap-xhdpi/cp_tx_k.png deleted file mode 100644 index a13d19d4..00000000 Binary files a/moduleUtil/src/main/res/mipmap-xhdpi/cp_tx_k.png and /dev/null differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/cp_tx_k.webp b/moduleUtil/src/main/res/mipmap-xhdpi/cp_tx_k.webp new file mode 100644 index 00000000..56109ed1 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/cp_tx_k.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/gift_wall_liang.webp b/moduleUtil/src/main/res/mipmap-xhdpi/gift_wall_liang.webp new file mode 100644 index 00000000..09f18ee7 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/gift_wall_liang.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/gift_wall_no_liang.webp b/moduleUtil/src/main/res/mipmap-xhdpi/gift_wall_no_liang.webp new file mode 100644 index 00000000..a44ea77a Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/gift_wall_no_liang.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/hourly_d.png b/moduleUtil/src/main/res/mipmap-xhdpi/hourly_d.png deleted file mode 100644 index b3c8c528..00000000 Binary files a/moduleUtil/src/main/res/mipmap-xhdpi/hourly_d.png and /dev/null differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/hourly_d.webp b/moduleUtil/src/main/res/mipmap-xhdpi/hourly_d.webp new file mode 100644 index 00000000..42373a86 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/hourly_d.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/hourly_xlh_status.png b/moduleUtil/src/main/res/mipmap-xhdpi/hourly_xlh_status.png deleted file mode 100644 index 551d1088..00000000 Binary files a/moduleUtil/src/main/res/mipmap-xhdpi/hourly_xlh_status.png and /dev/null differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/hourly_xlh_status.webp b/moduleUtil/src/main/res/mipmap-xhdpi/hourly_xlh_status.webp new file mode 100644 index 00000000..786de39f Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/hourly_xlh_status.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/icon_no.webp b/moduleUtil/src/main/res/mipmap-xhdpi/icon_no.webp new file mode 100644 index 00000000..43343fa6 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/icon_no.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/icon_noble_d.webp b/moduleUtil/src/main/res/mipmap-xhdpi/icon_noble_d.webp new file mode 100644 index 00000000..30abaa27 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/icon_noble_d.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/icon_noble_gz.webp b/moduleUtil/src/main/res/mipmap-xhdpi/icon_noble_gz.webp new file mode 100644 index 00000000..adf58223 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/icon_noble_gz.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/icon_noble_title.webp b/moduleUtil/src/main/res/mipmap-xhdpi/icon_noble_title.webp new file mode 100644 index 00000000..e6a8723c Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/icon_noble_title.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/icon_yes.webp b/moduleUtil/src/main/res/mipmap-xhdpi/icon_yes.webp new file mode 100644 index 00000000..bbe9f61f Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/icon_yes.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/me_edit.webp b/moduleUtil/src/main/res/mipmap-xhdpi/me_edit.webp new file mode 100644 index 00000000..06134b77 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/me_edit.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/me_gh.webp b/moduleUtil/src/main/res/mipmap-xhdpi/me_gh.webp new file mode 100644 index 00000000..4cc6e3f3 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/me_gh.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/me_help.webp b/moduleUtil/src/main/res/mipmap-xhdpi/me_help.webp new file mode 100644 index 00000000..5bfd8fee Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/me_help.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/me_home.webp b/moduleUtil/src/main/res/mipmap-xhdpi/me_home.webp new file mode 100644 index 00000000..8d111f18 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/me_home.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/me_income.webp b/moduleUtil/src/main/res/mipmap-xhdpi/me_income.webp new file mode 100644 index 00000000..76c39f56 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/me_income.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/me_invitation.webp b/moduleUtil/src/main/res/mipmap-xhdpi/me_invitation.webp new file mode 100644 index 00000000..44b0f3fc Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/me_invitation.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/me_my_bag.webp b/moduleUtil/src/main/res/mipmap-xhdpi/me_my_bag.webp new file mode 100644 index 00000000..15f2f466 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/me_my_bag.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/me_noble_bj.webp b/moduleUtil/src/main/res/mipmap-xhdpi/me_noble_bj.webp new file mode 100644 index 00000000..f812c44f Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/me_noble_bj.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/me_noble_image.webp b/moduleUtil/src/main/res/mipmap-xhdpi/me_noble_image.webp new file mode 100644 index 00000000..217b8aa6 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/me_noble_image.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/me_noble_no.webp b/moduleUtil/src/main/res/mipmap-xhdpi/me_noble_no.webp new file mode 100644 index 00000000..9e641fbe Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/me_noble_no.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/me_noble_xf.webp b/moduleUtil/src/main/res/mipmap-xhdpi/me_noble_xf.webp new file mode 100644 index 00000000..2e9df73c Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/me_noble_xf.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/me_opinion.webp b/moduleUtil/src/main/res/mipmap-xhdpi/me_opinion.webp new file mode 100644 index 00000000..0677cb63 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/me_opinion.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/me_recharge.webp b/moduleUtil/src/main/res/mipmap-xhdpi/me_recharge.webp new file mode 100644 index 00000000..523e4d50 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/me_recharge.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/me_setting.webp b/moduleUtil/src/main/res/mipmap-xhdpi/me_setting.webp new file mode 100644 index 00000000..9c982b0b Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/me_setting.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/me_show_store.webp b/moduleUtil/src/main/res/mipmap-xhdpi/me_show_store.webp new file mode 100644 index 00000000..2655552f Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/me_show_store.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/me_sj.webp b/moduleUtil/src/main/res/mipmap-xhdpi/me_sj.webp new file mode 100644 index 00000000..a271e389 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/me_sj.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/me_test.webp b/moduleUtil/src/main/res/mipmap-xhdpi/me_test.webp new file mode 100644 index 00000000..ab1fe8fe Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/me_test.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/me_zy.webp b/moduleUtil/src/main/res/mipmap-xhdpi/me_zy.webp new file mode 100644 index 00000000..86f3000a Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/me_zy.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/my_dan.webp b/moduleUtil/src/main/res/mipmap-xhdpi/my_dan.webp new file mode 100644 index 00000000..432b35d1 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/my_dan.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/my_noblesse.webp b/moduleUtil/src/main/res/mipmap-xhdpi/my_noblesse.webp new file mode 100644 index 00000000..e5b0badb Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/my_noblesse.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/noble_cz_ts.webp b/moduleUtil/src/main/res/mipmap-xhdpi/noble_cz_ts.webp new file mode 100644 index 00000000..4255fb65 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/noble_cz_ts.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/noble_details_bj.webp b/moduleUtil/src/main/res/mipmap-xhdpi/noble_details_bj.webp new file mode 100644 index 00000000..a3dd78fa Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/noble_details_bj.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/noble_details_tq.webp b/moduleUtil/src/main/res/mipmap-xhdpi/noble_details_tq.webp new file mode 100644 index 00000000..dcaf0c05 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/noble_details_tq.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/noble_duib.webp b/moduleUtil/src/main/res/mipmap-xhdpi/noble_duib.webp new file mode 100644 index 00000000..d6aad47d Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/noble_duib.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/noble_h_kt.webp b/moduleUtil/src/main/res/mipmap-xhdpi/noble_h_kt.webp new file mode 100644 index 00000000..91a82268 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/noble_h_kt.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/noble_is_lock.webp b/moduleUtil/src/main/res/mipmap-xhdpi/noble_is_lock.webp new file mode 100644 index 00000000..31eed752 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/noble_is_lock.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/noble_kt.webp b/moduleUtil/src/main/res/mipmap-xhdpi/noble_kt.webp new file mode 100644 index 00000000..16165ec3 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/noble_kt.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/noble_ljkt.webp b/moduleUtil/src/main/res/mipmap-xhdpi/noble_ljkt.webp new file mode 100644 index 00000000..1e3a1e7b Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/noble_ljkt.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/noble_ljsj.webp b/moduleUtil/src/main/res/mipmap-xhdpi/noble_ljsj.webp new file mode 100644 index 00000000..e21d3fe8 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/noble_ljsj.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/noble_seccer.webp b/moduleUtil/src/main/res/mipmap-xhdpi/noble_seccer.webp new file mode 100644 index 00000000..c7921b3a Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/noble_seccer.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/noble_sj.webp b/moduleUtil/src/main/res/mipmap-xhdpi/noble_sj.webp new file mode 100644 index 00000000..24eb70a2 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/noble_sj.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/noble_xf.webp b/moduleUtil/src/main/res/mipmap-xhdpi/noble_xf.webp new file mode 100644 index 00000000..aa416da2 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/noble_xf.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/noble_yxq.webp b/moduleUtil/src/main/res/mipmap-xhdpi/noble_yxq.webp new file mode 100644 index 00000000..30c546ed Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/noble_yxq.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/noble_zf_bj.webp b/moduleUtil/src/main/res/mipmap-xhdpi/noble_zf_bj.webp new file mode 100644 index 00000000..6c005c25 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/noble_zf_bj.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/personality.webp b/moduleUtil/src/main/res/mipmap-xhdpi/personality.webp new file mode 100644 index 00000000..c1940724 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/personality.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/ranking_user_cp_k.png b/moduleUtil/src/main/res/mipmap-xhdpi/ranking_user_cp_k.png deleted file mode 100644 index 83de7d45..00000000 Binary files a/moduleUtil/src/main/res/mipmap-xhdpi/ranking_user_cp_k.png and /dev/null differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/ranking_user_cp_k.webp b/moduleUtil/src/main/res/mipmap-xhdpi/ranking_user_cp_k.webp new file mode 100644 index 00000000..142766cd Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/ranking_user_cp_k.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/top1.png b/moduleUtil/src/main/res/mipmap-xhdpi/top1.png deleted file mode 100644 index d72b1dd6..00000000 Binary files a/moduleUtil/src/main/res/mipmap-xhdpi/top1.png and /dev/null differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/top1.webp b/moduleUtil/src/main/res/mipmap-xhdpi/top1.webp new file mode 100644 index 00000000..17c1166a Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/top1.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/top2.png b/moduleUtil/src/main/res/mipmap-xhdpi/top2.png deleted file mode 100644 index 1f22194b..00000000 Binary files a/moduleUtil/src/main/res/mipmap-xhdpi/top2.png and /dev/null differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/top2.webp b/moduleUtil/src/main/res/mipmap-xhdpi/top2.webp new file mode 100644 index 00000000..4d7b4e44 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/top2.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/top3.png b/moduleUtil/src/main/res/mipmap-xhdpi/top3.png deleted file mode 100644 index 1722d49b..00000000 Binary files a/moduleUtil/src/main/res/mipmap-xhdpi/top3.png and /dev/null differ diff --git a/moduleUtil/src/main/res/mipmap-xhdpi/top3.webp b/moduleUtil/src/main/res/mipmap-xhdpi/top3.webp new file mode 100644 index 00000000..74de3681 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xhdpi/top3.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/arrow_right.png b/moduleUtil/src/main/res/mipmap-xxhdpi/arrow_right.png new file mode 100644 index 00000000..a015760f Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/arrow_right.png differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/beautiful.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/beautiful.webp new file mode 100644 index 00000000..23723478 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/beautiful.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/cp_tx_k.png b/moduleUtil/src/main/res/mipmap-xxhdpi/cp_tx_k.png deleted file mode 100644 index 36b86ae2..00000000 Binary files a/moduleUtil/src/main/res/mipmap-xxhdpi/cp_tx_k.png and /dev/null differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/cp_tx_k.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/cp_tx_k.webp new file mode 100644 index 00000000..adb60f0f Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/cp_tx_k.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/dcl.png b/moduleUtil/src/main/res/mipmap-xxhdpi/dcl.png deleted file mode 100644 index c481a850..00000000 Binary files a/moduleUtil/src/main/res/mipmap-xxhdpi/dcl.png and /dev/null differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/dcl.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/dcl.webp new file mode 100644 index 00000000..0bcdd1aa Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/dcl.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/dcl2.png b/moduleUtil/src/main/res/mipmap-xxhdpi/dcl2.png deleted file mode 100644 index 2e39dad4..00000000 Binary files a/moduleUtil/src/main/res/mipmap-xxhdpi/dcl2.png and /dev/null differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/dcl2.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/dcl2.webp new file mode 100644 index 00000000..a361deff Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/dcl2.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/dcl3.png b/moduleUtil/src/main/res/mipmap-xxhdpi/dcl3.png deleted file mode 100644 index 3b8f44c0..00000000 Binary files a/moduleUtil/src/main/res/mipmap-xxhdpi/dcl3.png and /dev/null differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/dcl3.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/dcl3.webp new file mode 100644 index 00000000..d421a1a2 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/dcl3.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/dcl4.png b/moduleUtil/src/main/res/mipmap-xxhdpi/dcl4.png deleted file mode 100644 index fd420efa..00000000 Binary files a/moduleUtil/src/main/res/mipmap-xxhdpi/dcl4.png and /dev/null differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/dcl4.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/dcl4.webp new file mode 100644 index 00000000..ef58375e Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/dcl4.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/dcl5.png b/moduleUtil/src/main/res/mipmap-xxhdpi/dcl5.png deleted file mode 100644 index 3b8f44c0..00000000 Binary files a/moduleUtil/src/main/res/mipmap-xxhdpi/dcl5.png and /dev/null differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/dcl5.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/dcl5.webp new file mode 100644 index 00000000..d421a1a2 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/dcl5.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/dcl6.png b/moduleUtil/src/main/res/mipmap-xxhdpi/dcl6.png deleted file mode 100644 index 2e39dad4..00000000 Binary files a/moduleUtil/src/main/res/mipmap-xxhdpi/dcl6.png and /dev/null differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/dcl6.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/dcl6.webp new file mode 100644 index 00000000..a361deff Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/dcl6.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/gift_wall_liang.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/gift_wall_liang.webp new file mode 100644 index 00000000..5aedaa0c Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/gift_wall_liang.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/gift_wall_no_liang.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/gift_wall_no_liang.webp new file mode 100644 index 00000000..faeffa3b Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/gift_wall_no_liang.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/hourly_djs.png b/moduleUtil/src/main/res/mipmap-xxhdpi/hourly_djs.png deleted file mode 100644 index 9cde5882..00000000 Binary files a/moduleUtil/src/main/res/mipmap-xxhdpi/hourly_djs.png and /dev/null differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/hourly_djs.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/hourly_djs.webp new file mode 100644 index 00000000..e35fb398 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/hourly_djs.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/hourly_num.png b/moduleUtil/src/main/res/mipmap-xxhdpi/hourly_num.png deleted file mode 100644 index dc600c80..00000000 Binary files a/moduleUtil/src/main/res/mipmap-xxhdpi/hourly_num.png and /dev/null differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/hourly_num.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/hourly_num.webp new file mode 100644 index 00000000..68b052f9 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/hourly_num.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/hourly_wh.png b/moduleUtil/src/main/res/mipmap-xxhdpi/hourly_wh.png deleted file mode 100644 index dff1bf39..00000000 Binary files a/moduleUtil/src/main/res/mipmap-xxhdpi/hourly_wh.png and /dev/null differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/hourly_wh.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/hourly_wh.webp new file mode 100644 index 00000000..8cbf5ef5 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/hourly_wh.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/icon_no.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/icon_no.webp new file mode 100644 index 00000000..98164e4d Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/icon_no.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/icon_noble_d.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/icon_noble_d.webp new file mode 100644 index 00000000..cc5f66fa Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/icon_noble_d.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/icon_noble_gz.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/icon_noble_gz.webp new file mode 100644 index 00000000..65ed8e14 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/icon_noble_gz.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/icon_noble_title.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/icon_noble_title.webp new file mode 100644 index 00000000..5141addb Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/icon_noble_title.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/icon_yes.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/icon_yes.webp new file mode 100644 index 00000000..534f03ab Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/icon_yes.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/me_edit.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/me_edit.webp new file mode 100644 index 00000000..c6151e01 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/me_edit.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/me_gh.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/me_gh.webp new file mode 100644 index 00000000..e987d936 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/me_gh.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/me_help.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/me_help.webp new file mode 100644 index 00000000..70dbc436 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/me_help.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/me_home.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/me_home.webp new file mode 100644 index 00000000..7342a55e Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/me_home.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/me_income.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/me_income.webp new file mode 100644 index 00000000..f6f0ca61 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/me_income.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/me_invitation.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/me_invitation.webp new file mode 100644 index 00000000..affc3f90 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/me_invitation.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/me_my_bag.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/me_my_bag.webp new file mode 100644 index 00000000..919c51b9 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/me_my_bag.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/me_noble_bj.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/me_noble_bj.webp new file mode 100644 index 00000000..62a1e1b1 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/me_noble_bj.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/me_noble_image.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/me_noble_image.webp new file mode 100644 index 00000000..3f045829 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/me_noble_image.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/me_noble_no.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/me_noble_no.webp new file mode 100644 index 00000000..cba7a916 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/me_noble_no.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/me_noble_xf.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/me_noble_xf.webp new file mode 100644 index 00000000..fb2e3c97 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/me_noble_xf.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/me_opinion.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/me_opinion.webp new file mode 100644 index 00000000..aa61cd57 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/me_opinion.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/me_recharge.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/me_recharge.webp new file mode 100644 index 00000000..40744ff9 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/me_recharge.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/me_setting.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/me_setting.webp new file mode 100644 index 00000000..0bda0f8b Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/me_setting.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/me_show_store.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/me_show_store.webp new file mode 100644 index 00000000..3fc4a71c Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/me_show_store.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/me_sj.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/me_sj.webp new file mode 100644 index 00000000..c5a98650 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/me_sj.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/me_test.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/me_test.webp new file mode 100644 index 00000000..502b1562 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/me_test.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/me_zy.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/me_zy.webp new file mode 100644 index 00000000..30bc125d Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/me_zy.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/my_dan.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/my_dan.webp new file mode 100644 index 00000000..8bda3f65 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/my_dan.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/my_noblesse.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/my_noblesse.webp new file mode 100644 index 00000000..9d81f72a Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/my_noblesse.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/noble_bj.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/noble_bj.webp new file mode 100644 index 00000000..5b709800 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/noble_bj.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/noble_cz_ts.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/noble_cz_ts.webp new file mode 100644 index 00000000..3a7cf609 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/noble_cz_ts.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/noble_details_bj.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/noble_details_bj.webp new file mode 100644 index 00000000..934f7f71 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/noble_details_bj.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/noble_details_tq.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/noble_details_tq.webp new file mode 100644 index 00000000..cebaa14a Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/noble_details_tq.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/noble_duib.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/noble_duib.webp new file mode 100644 index 00000000..151f0115 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/noble_duib.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/noble_h_kt.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/noble_h_kt.webp new file mode 100644 index 00000000..3cbc500a Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/noble_h_kt.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/noble_is_lock.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/noble_is_lock.webp new file mode 100644 index 00000000..27be44f8 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/noble_is_lock.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/noble_kt.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/noble_kt.webp new file mode 100644 index 00000000..475489a2 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/noble_kt.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/noble_ljkt.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/noble_ljkt.webp new file mode 100644 index 00000000..d70947b0 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/noble_ljkt.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/noble_ljsj.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/noble_ljsj.webp new file mode 100644 index 00000000..99430b3a Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/noble_ljsj.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/noble_seccer.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/noble_seccer.webp new file mode 100644 index 00000000..8eb9bdd7 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/noble_seccer.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/noble_sj.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/noble_sj.webp new file mode 100644 index 00000000..62a2a209 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/noble_sj.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/noble_xf.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/noble_xf.webp new file mode 100644 index 00000000..56bf4353 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/noble_xf.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/noble_yxq.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/noble_yxq.webp new file mode 100644 index 00000000..33522b38 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/noble_yxq.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/noble_zf_bj.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/noble_zf_bj.webp new file mode 100644 index 00000000..c1dbcf3f Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/noble_zf_bj.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/personality.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/personality.webp new file mode 100644 index 00000000..8e9e8320 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/personality.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/ranking_user_cp_k.png b/moduleUtil/src/main/res/mipmap-xxhdpi/ranking_user_cp_k.png deleted file mode 100644 index d2344065..00000000 Binary files a/moduleUtil/src/main/res/mipmap-xxhdpi/ranking_user_cp_k.png and /dev/null differ diff --git a/moduleUtil/src/main/res/mipmap-xxhdpi/ranking_user_cp_k.webp b/moduleUtil/src/main/res/mipmap-xxhdpi/ranking_user_cp_k.webp new file mode 100644 index 00000000..d5c50af1 Binary files /dev/null and b/moduleUtil/src/main/res/mipmap-xxhdpi/ranking_user_cp_k.webp differ diff --git a/moduleUtil/src/main/res/mipmap-xxxhdpi/me_edit.webp b/moduleUtil/src/main/res/mipmap-xxxhdpi/me_edit.webp deleted file mode 100644 index b79e252d..00000000 Binary files a/moduleUtil/src/main/res/mipmap-xxxhdpi/me_edit.webp and /dev/null differ diff --git a/moduleUtil/src/main/res/mipmap-xxxhdpi/me_my_bag.webp b/moduleUtil/src/main/res/mipmap-xxxhdpi/me_my_bag.webp deleted file mode 100644 index e5698b10..00000000 Binary files a/moduleUtil/src/main/res/mipmap-xxxhdpi/me_my_bag.webp and /dev/null differ diff --git a/moduleUtil/src/main/res/mipmap-xxxhdpi/me_test.webp b/moduleUtil/src/main/res/mipmap-xxxhdpi/me_test.webp deleted file mode 100644 index 08de7ab4..00000000 Binary files a/moduleUtil/src/main/res/mipmap-xxxhdpi/me_test.webp and /dev/null differ diff --git a/moduleUtil/src/main/res/mipmap-xxxhdpi/me_wallet.webp b/moduleUtil/src/main/res/mipmap-xxxhdpi/me_wallet.webp deleted file mode 100644 index 4d37de33..00000000 Binary files a/moduleUtil/src/main/res/mipmap-xxxhdpi/me_wallet.webp and /dev/null differ diff --git a/moduleUtil/src/main/res/mipmap-xxxhdpi/my_dan.webp b/moduleUtil/src/main/res/mipmap-xxxhdpi/my_dan.webp deleted file mode 100644 index d428212f..00000000 Binary files a/moduleUtil/src/main/res/mipmap-xxxhdpi/my_dan.webp and /dev/null differ diff --git a/moduleUtil/src/main/res/mipmap-xxxhdpi/personality.webp b/moduleUtil/src/main/res/mipmap-xxxhdpi/personality.webp deleted file mode 100644 index d86ef41a..00000000 Binary files a/moduleUtil/src/main/res/mipmap-xxxhdpi/personality.webp and /dev/null differ diff --git a/moduleUtil/src/main/res/values/strings.xml b/moduleUtil/src/main/res/values/strings.xml index 31466a8c..e550098f 100644 --- a/moduleUtil/src/main/res/values/strings.xml +++ b/moduleUtil/src/main/res/values/strings.xml @@ -4,13 +4,17 @@ 羽声语音 语圈 钱包 - 段位 + 等级 公会中心 个性装扮 道具商城 我的背包 每日任务 消息 + 设置 + + 未点亮 + 已点亮 消息通知 未成年人模式 diff --git a/modulecircle/src/main/java/com/example/modulecircle/adapter/ExpandColumnAdapter.java b/modulecircle/src/main/java/com/example/modulecircle/adapter/ExpandColumnAdapter.java index 5c2d95a3..f6100ed6 100644 --- a/modulecircle/src/main/java/com/example/modulecircle/adapter/ExpandColumnAdapter.java +++ b/modulecircle/src/main/java/com/example/modulecircle/adapter/ExpandColumnAdapter.java @@ -1,5 +1,6 @@ package com.example.modulecircle.adapter; +import android.graphics.Color; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; @@ -53,6 +54,7 @@ public class ExpandColumnAdapter extends BaseQuickAdapter list; if (activitiesPermission != null) { + mBinding.dvr.setVisibility(View.VISIBLE); list = new ArrayList<>(); if (activitiesPermission.getFirst_charge_permission() == 1) { PermissionPicBean bean = new PermissionPicBean(); @@ -945,6 +946,8 @@ public class MainActivity extends BaseMvpActivity - - - - - - - - - + + + + + + + + + - + android:orientation="horizontal" + android:visibility="gone" + tools:visibility="visible"> + + + + (), // 初始化礼物管理器 GiftDisplayManager.getInstance().setupDisplayView(mBinding!!.giftContainer) + initPublicScreenFragment() } @@ -624,10 +627,10 @@ class RoomActivity : BaseMvpActivity(), mBinding!!.roomTop.tvNum.text = number.toString() + "" setviewyc(true) - initPublicScreenFragment() + // 确保Fragment已完全初始化后再调用getUpRoomInfo if (publicScreenFragment != null && publicScreenFragment!!.isAdded && publicScreenFragment!!.view != null) { - publicScreenFragment!!.getUpRoomInfo(resp) + publicScreenFragment!!.upRoomInfo(resp) } if (!isFinishing && !isDestroyed) { resetFragment() @@ -696,12 +699,6 @@ class RoomActivity : BaseMvpActivity(), mBinding!!.rlMisc.visibility = View.GONE } setupEffectView() - // 使用Handler延迟执行,确保Fragment视图已完全创建 - Handler(Looper.getMainLooper()).post { - if (publicScreenFragment != null && publicScreenFragment!!.isAdded && publicScreenFragment!!.view != null) { - publicScreenFragment!!.getUpRoomInfo(resp) - } - } if (mRoomInfoResp!!.gift_cycle != null && mRoomInfoResp!!.gift_cycle.xlh_info != null && mRoomInfoResp!!.gift_cycle.xlh_info.xlh_status != null && mRoomInfoResp!!.gift_cycle.xlh_info.xlh_status == "1") { mBinding?.xlhRk?.visibility = View.VISIBLE @@ -720,7 +717,7 @@ class RoomActivity : BaseMvpActivity(), private fun checkAndRestoreMinimizeState() { - val prefs = getSharedPreferences("room_minimize_state", Context.MODE_PRIVATE) + val prefs = getSharedPreferences("room_minimize_state", MODE_PRIVATE) var isMinimized = prefs.getBoolean("is_minimized", false) if (isMinimized) { @@ -1184,7 +1181,7 @@ class RoomActivity : BaseMvpActivity(), override fun initData() { if (!EasyPermissions.hasPermissions(this, *permissions)) { - PermissionDescriptionHelper.addPermissionDescription(false,mBinding?.root as ViewGroup,permissions) + PermissionDescriptionHelper.addPermissionDescription(false, mBinding?.root as ViewGroup, permissions) EasyPermissions.requestPermissions( this, "请开启录音使用权限", 1, *permissions @@ -1240,7 +1237,7 @@ class RoomActivity : BaseMvpActivity(), this, LinearLayoutManager.HORIZONTAL, false ) likeUserAdapter = LikeUserAdapter() - mBinding!!.roomTop.userRecyclerView.adapter = likeUserAdapter + mBinding?.roomTop?.userRecyclerView?.adapter = likeUserAdapter likeUserAdapter!!.onItemClickListener = BaseQuickAdapter.OnItemClickListener { adapter, view, position -> // RoomOnlineDialogFragment.show(roomId, "", mRoomUserBean, mRoomInfoResp, getSupportFragmentManager()); @@ -1342,13 +1339,10 @@ class RoomActivity : BaseMvpActivity(), private fun initPublicScreenFragment() { - // 检查是否已经存在 Fragment 实例(例如在配置更改后) - publicScreenFragment = supportFragmentManager - .findFragmentById(R.id.ease_container) as PublicScreenEaseChatFragment? // 如果不存在,则创建新的实例 if (publicScreenFragment == null) { - publicScreenFragment = PublicScreenEaseChatFragment.newInstance(roomId) + publicScreenFragment = PublicScreenEaseChatFragment.newInstance(mRoomInfoResp) supportFragmentManager.beginTransaction() .replace(R.id.ease_container, publicScreenFragment!!) .commitAllowingStateLoss() @@ -1436,7 +1430,7 @@ class RoomActivity : BaseMvpActivity(), } else if (msgType == 1011) { handleMsgType1011(messageEvent, text) } else if (msgType == 1001) { - handleMsgType1001() + handleMsgType1001(messageEvent) } else if (msgType == 1002) { handleMsgType1002(messageEvent, text) } else if (msgType == 1029) { @@ -1702,11 +1696,14 @@ class RoomActivity : BaseMvpActivity(), toPitNumber: String, messageEvent: RoomMessageEvent ) { - mRoomInfoResp!!.user_info.pit_number = Integer.parseInt(toPitNumber) - if ("9" == toPitNumber && messageEvent.text.user_id.equals(SpUtil.getUserId().toString())) { + + if ("9" == toPitNumber && messageEvent.text.fromUserInfo.user_id == SpUtil.getUserId()) { + mRoomInfoResp!!.user_info.pit_number = Integer.parseInt(toPitNumber) mBinding!!.roomTop.rl.visibility = View.VISIBLE ivSoundEffects(true) + + } else { if (customMusicFloatingView != null) { customMusicFloatingView!!.destroy() @@ -1740,6 +1737,7 @@ class RoomActivity : BaseMvpActivity(), if (mRoomInfoResp!!.user_info.pit_number == 9) { mBinding!!.roomTop.rl.visibility = View.VISIBLE ivSoundEffects(true) + setRoleType(3, 9) } } @@ -1871,10 +1869,8 @@ class RoomActivity : BaseMvpActivity(), aBoolean = false ivWheatFeeding(com.xscm.moduleutil.R.mipmap.room_wheat_feeding_up) setBoolean(aBoolean) - if (mRoomInfoResp!!.user_info != null) { - mRoomInfoResp!!.user_info.pit_number = - pitNumber?.toInt() ?: -1 - } + mRoomInfoResp?.user_info?.pit_number = + pitNumber?.toInt() ?: -1 setRoleType(3, pitNumber!!.toInt()) switchMic(2) } @@ -1893,21 +1889,6 @@ class RoomActivity : BaseMvpActivity(), } else if ("3" == typeId || "4" == typeId || "1" == typeId || "8" == typeId) { val labelId = mRoomInfoResp!!.room_info.label_id if ("2" == labelId) { -// val pitBean = RoomPitBean() -// pitBean.pit_number = messageEvent.text.pit_number -// pitBean.user_id = messageEvent.text.fromUserInfo.user_id.toString() + "" -// pitBean.avatar = messageEvent.text.fromUserInfo.avatar -// pitBean.nickname = messageEvent.text.fromUserInfo.nickname -// pitBean.sex = messageEvent.text.fromUserInfo.sex.toString() + "" -// pitBean.charm = messageEvent.text.fromUserInfo.charm -// pitBean.dress = messageEvent.text.fromUserInfo.dress -// -// if (pitBean.pit_number == "9") { -// val roomDefaultWheatView: RoomKtvWheatView = mBinding?.roomTop!!.muZc -// roomDefaultWheatView.setData(pitBean) -// } - - roomFragment!!.KtvFragmentEvent(messageEvent) } else if ("1" == labelId) { mRoomInfoResp!!.room_info.pit_list.set(pitNumber.toInt() - 1, getPitBean(messageEvent)) @@ -1922,12 +1903,6 @@ class RoomActivity : BaseMvpActivity(), } else { roomFragment!!.updateSeatViewExchangedWithPitArray(mRoomInfoResp) } - - // if (pitNumber.equals("9") && mRoomInfoResp.getUser_info().getUser_id().equals(SpUtil.getUserId()+"")) { -// ivSoundEffects(true); -// } else { -// ivSoundEffects(false); -// } } private fun handleMsgType1004(messageEvent: RoomMessageEvent, text: T?) { @@ -1938,14 +1913,11 @@ class RoomActivity : BaseMvpActivity(), val pitNumber = text.pit_number val userId = fromUserInfo.user_id val currentUserId = SpUtil.getUserId() - if (userId == currentUserId) { aBoolean = true ivWheatFeeding(com.xscm.moduleutil.R.mipmap.room_wheat_feeding) setBoolean(aBoolean) - if (mRoomInfoResp!!.user_info != null) { - mRoomInfoResp!!.user_info.pit_number = 0 - } + mRoomInfoResp?.user_info?.pit_number = 0 setRoleType(0, 0) switchMic(2) } @@ -1969,9 +1941,9 @@ class RoomActivity : BaseMvpActivity(), if ("9" == pitNumber) { if (userId == currentUserId) { mRoomInfoResp!!.room_info.pit_list[0] = getPitBean2(messageEvent, "9") - if (mRoomInfoResp!!.user_info != null) { - mRoomInfoResp!!.user_info.pit_number = 0 - } +// if (mRoomInfoResp!!.user_info != null) { +// mRoomInfoResp!!.user_info.pit_number = 0 +// } } } else if ("888" == pitNumber) { mRoomInfoResp!!.room_auction = null @@ -1985,17 +1957,6 @@ class RoomActivity : BaseMvpActivity(), } else if ("3" == typeId || "4" == typeId || "1" == typeId || "8" == typeId) { val labelId = mRoomInfoResp!!.room_info.label_id if ("2" == labelId) { -// val pitBean = RoomPitBean() -// pitBean.pit_number = messageEvent.text.pit_number -// pitBean.user_id = "" -// pitBean.avatar = "" -// pitBean.nickname = "" -// pitBean.sex = "" -// pitBean.charm = "" -// if (pitBean.pit_number == "9") { -// val roomDefaultWheatView: RoomKtvWheatView = mBinding?.roomTop!!.muZc -// roomDefaultWheatView.setData(pitBean) -// } roomFragment!!.KtvFragmentEvent(messageEvent) } else if ("1" == labelId) { mRoomInfoResp!!.room_info.pit_list.set(pitNumber.toInt() - 1, getPitBean2(messageEvent, pitNumber)) @@ -2090,10 +2051,125 @@ class RoomActivity : BaseMvpActivity(), performExitRoom(1); } } + private var currentMqttView: View? = null // 正在播放 + var decorView: ViewGroup? = null //礼物的 - private fun handleMsgType1001() { - number++ - mBinding!!.roomTop.tvNum.text = number.toString() + "" + + private fun handleMsgType1001(roomMessageEvent: RoomMessageEvent) { + if (roomMessageEvent.text.fromUserInfo.enter_image?.isNotEmpty() == true){ + showFloatingMessage(roomMessageEvent.text.fromUserInfo) + } +// number++ +// mBinding!!.roomTop.tvNum.text = number.toString() + "" + } + private fun showFloatingMessage(userInfo: UserInfo) { + try { + // 清理之前的视图(如果存在) + if ( currentMqttView?.getParent() != null) { + val parent = currentMqttView?.getParent() as ViewGroup + parent.removeView(currentMqttView) + } + + if (decorView == null) { + decorView = getWindow().getDecorView() as ViewGroup? + } + + currentMqttView = LayoutInflater.from(this).inflate(R.layout.item_noble_piaoping, null) + val layoutParams = FrameLayout.LayoutParams( + FrameLayout.LayoutParams.MATCH_PARENT, + FrameLayout.LayoutParams.WRAP_CONTENT + ) + layoutParams.topMargin = DisplayUtil.dip2px(this, 300f) + layoutParams.gravity = Gravity.TOP or Gravity.CENTER_HORIZONTAL + currentMqttView?.setLayoutParams(layoutParams) + decorView?.addView(currentMqttView) + currentMqttView?.let { updateFloatingViewData(it, userInfo) } + + currentMqttView?.let { + resetAndStartMqttAnimation(it, Runnable { + // 清理当前视图 + if (currentMqttView?.getParent() != null) { + val parent = currentMqttView?.getParent() as ViewGroup + parent.removeView(currentMqttView) + } + currentMqttView = null + + }) + } + } catch (e: java.lang.Exception) { + + } + } + private fun resetAndStartMqttAnimation(view: View, onAnimationEnd: Runnable) { + try { + val screenWidth = getScreenWidth() + // 设置初始位置:在屏幕右侧外部(完全不可见) + view.setTranslationX(screenWidth.toFloat()) + + + val enterAnim = TranslateAnimation( + Animation.ABSOLUTE, screenWidth.toFloat(), + Animation.ABSOLUTE, ((screenWidth - SystemUtils.getWidth(316)) / 2).toFloat(), + Animation.ABSOLUTE, 0f, + Animation.ABSOLUTE, 0f + ) + enterAnim.setDuration(1500) + enterAnim.setInterpolator(DecelerateInterpolator(2.0f)) + enterAnim.setAnimationListener(object : Animation.AnimationListener { + override fun onAnimationStart(animation: Animation?) { + } + + override fun onAnimationEnd(animation: Animation?) { + // 停留后退出 + CommonAppContext.postDelayed(Runnable { + val exitAnim = TranslateAnimation( + Animation.ABSOLUTE, ((screenWidth - SystemUtils.getWidth(316)) / 2).toFloat(), + Animation.ABSOLUTE, -screenWidth.toFloat(), + Animation.ABSOLUTE, 0f, + Animation.ABSOLUTE, 0f + ) + exitAnim.setDuration(3000) + exitAnim.setInterpolator(DecelerateInterpolator(2f)) + exitAnim.setAnimationListener(object : Animation.AnimationListener { + override fun onAnimationStart(animation: Animation?) { + } + + override fun onAnimationEnd(animation: Animation?) { + // 移除视图并处理下一个 + onAnimationEnd.run() + } + + override fun onAnimationRepeat(animation: Animation?) { + } + }) + view.startAnimation(exitAnim) + }, 5000) // 停留1秒 + } + + override fun onAnimationRepeat(animation: Animation?) { + } + }) + view.startAnimation(enterAnim) + } catch (e: java.lang.Exception) { + LogUtils.e("MQTT动画启动失败", e) + onAnimationEnd.run() + } + } + private fun getScreenWidth(): Int { + val displayMetrics = DisplayMetrics() + if (getWindowManager() != null) { + getWindowManager().getDefaultDisplay().getMetrics(displayMetrics) + return displayMetrics.widthPixels + } + return getResources().getDisplayMetrics().widthPixels + } + + private fun updateFloatingViewData(view: View, userInfo: UserInfo) { + val textView = view.findViewById(R.id.tv_name) + val im_bj = view.findViewById(R.id.im_bj) + + textView.text = userInfo.enter_text + ImageUtils.loadHeadCC(userInfo.enter_image, im_bj) } private fun handleMsgType1002(messageEvent: RoomMessageEvent, text: T?) { @@ -2658,13 +2734,13 @@ class RoomActivity : BaseMvpActivity(), // if (mRoomInfoResp!!.room_info.label_id == "1") { // queren() // } else { - val fragment = RequestDialogFragment.show( - roomId, mRoomInfoResp, 1, - supportFragmentManager - ) - if (fragment != null) { - addActiveDialogFragment(fragment) // 添加到管理列表 - } + val fragment = RequestDialogFragment.show( + roomId, mRoomInfoResp, 1, + supportFragmentManager + ) + if (fragment != null) { + addActiveDialogFragment(fragment) // 添加到管理列表 + } // } } else if (id == R.id.rl_gift) { //礼物 // RoomGiftDialogFragment.show(mRoomInfoResp, null, roomId, 0, "", getSupportFragmentManager()); @@ -2806,7 +2882,7 @@ class RoomActivity : BaseMvpActivity(), } if (mRoomInfoResp!!.room_info.label_id != "6") { val activityManager = - getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager + getSystemService(ACTIVITY_SERVICE) as ActivityManager val appProcesses = activityManager.runningAppProcesses ?: return false @@ -2871,7 +2947,7 @@ class RoomActivity : BaseMvpActivity(), } private fun saveMinimizeState() { - val prefs = getSharedPreferences("room_minimize_state", Context.MODE_PRIVATE) + val prefs = getSharedPreferences("room_minimize_state", MODE_PRIVATE) val editor = prefs.edit() editor.putString(PREF_MINIMIZED_ROOM, roomId) editor.putLong(PREF_MINIMIZED_TIME, System.currentTimeMillis()) @@ -2880,7 +2956,7 @@ class RoomActivity : BaseMvpActivity(), } private fun clearMinimizeState() { - val prefs = getSharedPreferences("room_minimize_state", Context.MODE_PRIVATE) + val prefs = getSharedPreferences("room_minimize_state", MODE_PRIVATE) val editor = prefs.edit() editor.remove(PREF_MINIMIZED_ROOM) editor.remove(PREF_MINIMIZED_TIME) @@ -2889,7 +2965,7 @@ class RoomActivity : BaseMvpActivity(), } private fun wasMinimized(): Boolean { - val prefs = getSharedPreferences("room_minimize_state", Context.MODE_PRIVATE) + val prefs = getSharedPreferences("room_minimize_state", MODE_PRIVATE) return prefs.getBoolean("is_minimized", false) } @@ -3014,7 +3090,7 @@ class RoomActivity : BaseMvpActivity(), val typeId = mRoomInfoResp!!.room_info.type_id val labelId = mRoomInfoResp!!.room_info.label_id - val userPitNumber = mRoomInfoResp!!.user_info.pit_number + val userPitNumber = mRoomInfoResp?.user_info?.pit_number!! // 情况1: typeId = 6 时,只显示消息按钮 if ("6" == typeId) { @@ -3078,14 +3154,17 @@ class RoomActivity : BaseMvpActivity(), switchMic(2) // 关闭麦克风 } } + pit_number == 888 -> { rl_mic?.visibility = View.VISIBLE switchMic(2) // 关闭麦克风 } + pit_number == -1 -> { rl_mic?.visibility = View.VISIBLE switchMic(1) // 打开麦克风 } + else -> { rl_mic?.visibility = View.GONE switchMic(2) // 关闭麦克风 @@ -3102,7 +3181,7 @@ class RoomActivity : BaseMvpActivity(), if ("1" != typeId) { rl_more?.visibility = View.GONE } - if ("1"==typeId && "2" == labelId){ + if ("1" == typeId && "2" == labelId) { rl_misc?.visibility = View.VISIBLE } } @@ -3215,7 +3294,7 @@ class RoomActivity : BaseMvpActivity(), dialog.setOnShowListener { etContent.requestFocus() val imm = - OkDownloadProvider.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + OkDownloadProvider.context.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager imm.showSoftInput(etContent, InputMethodManager.SHOW_IMPLICIT) } if (inputSting != null) { @@ -3468,8 +3547,8 @@ class RoomActivity : BaseMvpActivity(), ivSoundEffects(false) } // } - if (mRoomInfoResp!!.user_info.user_id == SpUtil.getUserId() - .toString() + "" && mRoomInfoResp!!.user_info.pit_number == 9 && mRoomInfoResp!!.room_info.type_id == "1" && mRoomInfoResp!!.room_info.label_id != "1" + if (mRoomInfoResp?.user_info?.user_id == SpUtil.getUserId() + .toString() + "" && mRoomInfoResp?.user_info?.pit_number == 9 && mRoomInfoResp?.room_info?.type_id == "1" && mRoomInfoResp?.room_info?.label_id != "1" ) { rlMore(true) } else { @@ -4144,6 +4223,7 @@ class RoomActivity : BaseMvpActivity(), GiftDisplayManager.getInstance().clearAll() mBinding!!.giftContainer.removeAllViews() CommonAppContext.getInstance().isMai = false + CommonAppContext.getInstance().playId = null // 确保父类的 onDestroy 被调用 super.finish() } @@ -4415,7 +4495,7 @@ class RoomActivity : BaseMvpActivity(), * @return 服务是否正在运行 */ private fun isServiceExisted(context: Context, serviceName: String): Boolean { - val manager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager + val manager = context.getSystemService(ACTIVITY_SERVICE) as ActivityManager if (manager != null) { val runningServices = manager.getRunningServices(Int.MAX_VALUE) for (serviceInfo in runningServices) { diff --git a/moduleroom/src/main/java/com/example/moduleroom/adapter/EaseChatAdapter.java b/moduleroom/src/main/java/com/example/moduleroom/adapter/EaseChatAdapter.java index e947f94c..fc3f2a12 100644 --- a/moduleroom/src/main/java/com/example/moduleroom/adapter/EaseChatAdapter.java +++ b/moduleroom/src/main/java/com/example/moduleroom/adapter/EaseChatAdapter.java @@ -40,17 +40,16 @@ import com.xscm.moduleutil.bean.GiftBean; import com.xscm.moduleutil.bean.RoomMessageEvent; import com.xscm.moduleutil.bean.UserInfo; import com.xscm.moduleutil.bean.room.EMMessageInfo; +import com.xscm.moduleutil.bean.room.EmotionDeatils; import com.xscm.moduleutil.utils.ColorManager; import com.xscm.moduleutil.utils.ImageUtils; +import com.xscm.moduleutil.utils.MeHeadView; import com.xscm.moduleutil.utils.logger.Logger; import com.xscm.moduleutil.widget.AdaptiveImageView; import com.xscm.moduleutil.widget.GifAvatarOvalView; import com.xscm.moduleutil.widget.img.BubbleBackgroundHelper; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Objects; +import java.util.*; /** @@ -215,9 +214,11 @@ public class EaseChatAdapter extends BaseMultiItemQuickAdapter() { - @Override - public boolean onResourceReady(Drawable resource, Object model, Target target, - DataSource dataSource, boolean isFirstResource) { - // 检查视图是否仍属于当前数据项 - if (uniqueId.equals(emojiImageView.getTag())) { - // 加载完成后执行 - new Handler().postDelayed(() -> { - // 再次检查视图状态 - if (uniqueId.equals(emojiImageView.getTag())) { - Glide.with(mContext) - .load(emMessage.getText().getEmoji().getImage()) - .into(emojiImageView); - } - }, 1500); + if (!emMessage.getText().getEmoji().getAnimate_image().isEmpty()) { + // 使用 RequestListener 监听加载完成 + Glide.with(mContext) + .load(emMessage.getText().getEmoji().getAnimate_image()) + .listener(new RequestListener() { + @Override + public boolean onResourceReady(Drawable resource, Object model, Target target, + DataSource dataSource, boolean isFirstResource) { + // 检查视图是否仍属于当前数据项 + if (uniqueId.equals(emojiImageView.getTag())) { + // 加载完成后执行 + new Handler().postDelayed(() -> { + // 再次检查视图状态 + if (uniqueId.equals(emojiImageView.getTag())) { + Glide.with(mContext) + .load(emMessage.getText().getEmoji().getImage()) + .into(emojiImageView); + } + }, 1500); + } + return false; } - return false; - } - @Override - public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, - boolean isFirstResource) { - return false; - } - }) - .into(emojiImageView); + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, + boolean isFirstResource) { + + return false; + } + }) + .into(emojiImageView); + }else { + Glide.with(mContext) + .load(emMessage.getText().getEmoji().getImage()) + .into(emojiImageView); + } } else { helper.getView(com.xscm.moduleutil.R.id.tv_content).setVisibility(View.VISIBLE); emojiImageView.setVisibility(View.GONE); @@ -579,7 +593,7 @@ public class EaseChatAdapter extends BaseMultiItemQuickAdapter { // 转换后的 Java 代码 private OnEmotionClickListener onEmotionClickListener; @@ -28,9 +32,17 @@ public class EmotionAdapter extends BaseQuickAdapter { + if (item.is_lock()==1){ + ToastUtils.show("当前属于爵位专属,请先开通爵位"); + return; + } if (onEmotionClickListener != null) { onEmotionClickListener.onEmotionClick(item); } diff --git a/moduleroom/src/main/java/com/example/moduleroom/dialog/RoomSettingFragment.java b/moduleroom/src/main/java/com/example/moduleroom/dialog/RoomSettingFragment.java index 9991fea8..8bc69f30 100644 --- a/moduleroom/src/main/java/com/example/moduleroom/dialog/RoomSettingFragment.java +++ b/moduleroom/src/main/java/com/example/moduleroom/dialog/RoomSettingFragment.java @@ -362,7 +362,6 @@ public class RoomSettingFragment extends BaseMvpDialogFragment { + // 确保在主线程更新 UI + if (getActivity() != null) { + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + handleRoomMessage(message); + } + }); } }; MessageListenerSingleton.getInstance().addPublicScreenMessageListener(messageListener); @@ -226,34 +159,16 @@ public class PublicScreenEaseChatFragment extends BaseMvpFragment cachedMessages = MessageListenerSingleton.getInstance().getAndClearCachedMessages(roomId); - if (!cachedMessages.isEmpty()) { - LogUtils.d("PublicScreenEaseChatFragment", "处理缓存消息数量: " + cachedMessages.size()); - for (RoomMessageEvent message : cachedMessages) { - handleRoomMessage(message); - } - } -// else { -// // 如果没有缓存消息,发送默认的欢迎消息 -// sendWelcomeMessage(); -// } + // 获取并处理缓存的消息 + List cachedMessages = MessageListenerSingleton.getInstance().getAndClearCachedMessages(roomId); + if (!cachedMessages.isEmpty()) { + LogUtils.d("PublicScreenEaseChatFragment", "处理缓存消息数量: " + cachedMessages.size()); + for (RoomMessageEvent message : cachedMessages) { + handleRoomMessage(message); } - }, 300); // 延迟300ms确保监听器已注册 + } } - /** - * 发送欢迎消息 - */ - private void sendWelcomeMessage() { - RoomMessageEvent.T t = new RoomMessageEvent.T(); - t.setText("羽声语音严禁未成年人进行直播或打赏,官方将24小时在线巡查。我们提倡绿色直播,直播间严禁出现涉政、涉恐、涉黄、涉赌等违法违规内容,严禁宣传封建迷信、宗教极端思想、出现低俗色情、吸烟酗酒等内容,严禁违反社会主义核心价值观、践踏社会道德底线、诱导打赏、低俗 PK 、买卖金币等行为,请大家共同遵守、监督并及时举报。请勿相信各类刷钻、购买礼包、游戏币及电商贩卖等非官方广告信息,谨防网络诈骗。"); - // 加入群组成功 - handleRoomMessage(new RoomMessageEvent(1000, roomId, t)); - } @Override protected void initListener() { @@ -283,45 +198,11 @@ public class PublicScreenEaseChatFragment extends BaseMvpFragment { -// EMMessageInfo item = easeChatAdapter.getItem(position); -// if (view.getId() == R.id.tv_red_rain_detail) { //点击红包结果详情 -// EMMessage emMessage = item != null ? item.getEmMessage() : null; -// if (emMessage == null) { -// return; -// } -// int red_rain_id = emMessage.getIntAttribute("record_id", 0); -// RainResultDetailFragment.Companion.newInstance(red_rain_id).show(getChildFragmentManager(), "红包雨详情"); -// } -// }); easeChatAdapter.setOnItemClickListener((adapter, view, position) -> { EMMessageInfo item = easeChatAdapter.getItem(position); RoomMessageEvent emMessage = item.getEmMessage(); if (emMessage.getText().getFromUserInfo() != null) { RoomUserInfoFragment.show(roomInfoResp.getRoom_info().getRoom_id(), emMessage.getText().getFromUserInfo().getUser_id() != 0 ? emMessage.getText().getFromUserInfo().getUser_id() + "" : emMessage.getText().getFromUserInfo().getId() + "", emMessage.getText().getFromUserInfo().getPit_number(), getHostUser(roomInfoResp.getUser_info()), false, 5, isNumberWhether(), getChildFragmentManager()); } -// String userId = item.getEmMessage().getStringAttribute("user_id", ""); -// if (!TextUtils.isEmpty(userId)) { -// EventBus.getDefault().post(new UserInfoShowEvent(roomInfoResp.getRoom_info().getRoom_id(), userId)); -// } }); -// // //判断是否开启公屏 setUpPublicScreen(); -// //是否隐藏欢迎动画 -// setEffectSwitch(SpUtils.getOpenEffect() == 1 ? new EffectEvent(true) : new EffectEvent(false)); mBinding.tvCount.setOnClickListener(this::onClick); -// mBinding.llVerticalScroll.setOnClickListener(this::onSwitcher); -// mBinding.tvTabAll.setOnClickListener(this::onClick); mBinding.tvTabUser.setOnClickListener(this::onClick); mBinding.tvTabSystem.setOnClickListener(this::onClick); @@ -410,126 +270,19 @@ public class PublicScreenEaseChatFragment extends BaseMvpFragment 0) { mBinding.recycleViewPublic.removeAllViews(); -// easeChatAdapter.clearData(); } mBinding.recycleViewPublic.setVisibility(View.VISIBLE);//开启消息列表 mBinding.llHeadTab.setVisibility(View.GONE); mBinding.tvClose.setVisibility(View.GONE); -// } else { -// mBinding.tvClose.setVisibility(View.VISIBLE); -// mBinding.llHeadTab.setVisibility(View.GONE); -// mBinding.recycleView.setVisibility(View.GONE);//隐藏消息列表 -// } count = 0;//未读数0 isBottom = true; } -// private void initSwitcher(List list) { -// if (countDownTimer != null) { -// mBinding.vfSwitcher.removeAllViews(); -// countDownTimer.cancel(); -// countDownTimer = null; -// } -// mBinding.vfSwitcher.stopFlipping(); -//// //队列最多保存十条数据 -//// vfSwitcher.removeAllViews(); -//// if (list.size() < queueMessageNum && oldList.size() > 0) { -//// for (int i = oldList.size() - 1; i > 0; i--) { -//// if (list.size() >= queueMessageNum) { -//// break; -//// } else { -//// list.add(oldList.get(i)); -//// } -//// } -//// } -// for (LuckyRankBean data : list) { -// View view = getLayoutInflater().inflate(R.layout.room_integral_item_mall_flipper, null); -// TextView textView = view.findViewById(R.id.tv_flipper_msg); -// String p = "许愿池"; -// if (!TextUtils.isEmpty(data.getTitle())) { -// p = data.getTitle(); -// } -// textView.setText(String.format("%s在%s获得%sX%s", data.getNickname(), p, data.getGift_name(), data.getGift_number())); -//// if (vfSwitcher.getChildCount() >= queueMessageNum) { -//// break; -//// } -// mBinding.vfSwitcher.addView(view); -// } -// int count = mBinding.vfSwitcher.getChildCount(); -// for (int i = 0; i < count - queueMessageNum; i++) { -// mBinding.vfSwitcher.removeViewAt(i); -// } -// mBinding.vfSwitcher.setInAnimation(requireContext(), R.anim.integral_flipper_in); -// mBinding.vfSwitcher.setOutAnimation(requireContext(), R.anim.integral_flipper_out); -// mBinding.vfSwitcher.setFlipInterval(5000); -// mBinding.vfSwitcher.setAutoStart(true); -// mBinding.vfSwitcher.startFlipping(); -// mBinding.llVerticalScroll.setBackground(ResourcesCompat.getDrawable(getResources(),R.drawable.room_bg_screen_gift_push,null)); -// mBinding.vfSwitcher.getInAnimation().setAnimationListener(new Animation.AnimationListener() { -// @Override -// public void onAnimationStart(Animation animation) { -// -// } -// -// @Override -// public void onAnimationRepeat(Animation animation) { -// -// } -// -// @Override -// public void onAnimationEnd(Animation animation) { -// //最后一个 -// if (mBinding.vfSwitcher.getDisplayedChild() == mBinding.vfSwitcher.getChildCount() - 1) { -// mBinding.vfSwitcher.stopFlipping(); -//// oldList.clear(); -// countDownTime(60); -// } -// } -// }); -// } - - /** - * 推送礼物显示计时 - * - * @param longTime - */ - public void countDownTime(long longTime) { - countDownTimer = new CountDownTimer(longTime * 1000, 1000) { - - @Override - public void onTick(long millisUntilFinished) { - - } - - @Override - public void onFinish() { - if (isAdded()) { - if (mBinding.vfSwitcher != null) { - mBinding.vfSwitcher.removeAllViews(); - } - if (mBinding.llVerticalScroll != null) { -// mBinding.llVerticalScroll.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.room_null, null)); - } - } - } - }; - countDownTimer.start(); - } @Override protected int getLayoutId() { @@ -539,11 +292,7 @@ public class PublicScreenEaseChatFragment extends BaseMvpFragment() { @Override public void onProgress(int progress) { @@ -620,153 +367,7 @@ public class PublicScreenEaseChatFragment extends BaseMvpFragment 0) { @@ -787,11 +388,11 @@ public class PublicScreenEaseChatFragment extends BaseMvpFragment() { @Override public void onProgress(int progress) { @@ -801,7 +402,6 @@ public class PublicScreenEaseChatFragment extends BaseMvpFragment 0) { mBinding.recycleViewPublic.scrollToPosition(itemCount - 1); } } else { count++; - if (mBinding.tvCount != null) { - mBinding.tvCount.setText(count + "条新消息"); - mBinding.tvCount.setVisibility(View.VISIBLE); - } + mBinding.tvCount.setText(count + "条新消息"); + mBinding.tvCount.setVisibility(View.VISIBLE); // 当未读消息过多时,限制数量显示 if (count > 99) { - if (mBinding.tvCount != null) { - mBinding.tvCount.setText("99+条新消息"); - } + mBinding.tvCount.setText("99+条新消息"); } } } @@ -1112,16 +687,6 @@ public class PublicScreenEaseChatFragment extends BaseMvpFragment - * // * @param roomInputEvent - */ -// @Subscribe(threadMode = ThreadMode.MAIN) -// public void sendTxtEvent(RoomInputEvent roomInputEvent) { -// RoomUserBean userBean = roomInfoResp.getUser_info(); -// EMMessage txtSendMessage = EMMessage.createTextSendMessage(roomInputEvent.text, toChatUsername); -// -// txtSendMessage.setAttribute("action", 2); -// txtSendMessage.setAttribute("type", EMMessageInfo.SRLiveRoomChatMsgTypeChat); -// txtSendMessage.setAttribute("user_id", userBean.getUser_id()); -// txtSendMessage.setAttribute("rank_icon", userBean.getRank_icon()); -// txtSendMessage.setAttribute("charm_icon", userBean.getCharm_icon()); -// txtSendMessage.setAttribute("nobility_icon", userBean.getNobility_icon()); -// txtSendMessage.setAttribute("user_title", BaseApplication.getInstance().getUser().getUser_title()); -// txtSendMessage.setAttribute("nickname", userBean.getNickname()); -// if (roomInfoResp.getRoom_info().getActual_role() == 5) { -// txtSendMessage.setAttribute("role", roomInfoResp.getRoom_info().getActual_role()); -// } else { -// txtSendMessage.setAttribute("role", roomInfoResp.getRoom_info().getRole()); -// } -// txtSendMessage.setAttribute("user_is_new", userBean.getUser_is_new()); -// txtSendMessage.setMsgTime(System.currentTimeMillis()); -// txtSendMessage.setLocalTime(System.currentTimeMillis()); -// easeChatAdapter.addData(new EMMessageInfo(txtSendMessage)); -// refreshSelectLast(); -// } - private void appendWelcomeMessage() { -// RoomUserBean userBean = roomInfoResp.getUser_info(); -// EMMessage txtSendMessage = EMMessage.createTxtSendMessage("加入直播间", toChatUsername); -// txtSendMessage.setAttribute("action", 3); -// txtSendMessage.setAttribute("charm_icon", userBean.getCharm_icon()); -// txtSendMessage.setAttribute("type", EMMessageInfo.SRLiveRoomChatMsgTypeGoInRoom); -// txtSendMessage.setAttribute("user_id", userBean.getUser_id()); -// txtSendMessage.setAttribute("rank_icon", userBean.getRank_icon()); -// txtSendMessage.setAttribute("charm_icon", userBean.getCharm_icon()); -// txtSendMessage.setAttribute("nobility_icon", userBean.getNobility_icon()); -// txtSendMessage.setAttribute("user_title", BaseApplication.getInstance().getUser().getUser_title()); -// txtSendMessage.setAttribute("nickname", userBean.getNickname()); -// if (roomInfoResp.getRoom_info().getActual_role() == 5) { -// txtSendMessage.setAttribute("role", roomInfoResp.getRoom_info().getActual_role()); -// } else { -// txtSendMessage.setAttribute("role", roomInfoResp.getRoom_info().getRole()); -// } -// -// txtSendMessage.setAttribute("user_is_new", userBean.getUser_is_new()); -// txtSendMessage.setMsgTime(System.currentTimeMillis()); -// txtSendMessage.setLocalTime(System.currentTimeMillis()); -// easeChatAdapter.addData(new EMMessageInfo(txtSendMessage)); - } - - private void appendMessage(int action, int type, String text) { -// EMMessage txtSendMessage = EMMessage.createTxtSendMessage(text, toChatUsername); -// txtSendMessage.setAttribute("action", action); -// txtSendMessage.setAttribute("type", type); -// txtSendMessage.setMsgTime(System.currentTimeMillis()); -// txtSendMessage.setLocalTime(System.currentTimeMillis()); -// easeChatAdapter.addData(new EMMessageInfo(txtSendMessage)); - } - - -// @Override -// public void onError(int i, String s) { -// Logger.e(TAG, "加入聊天室失败:code=" + i + " 信息: " + s); -// if (mBinding.recycleView != null) { -// mBinding.recycleView.removeCallbacks(joinChatRoomTask); -// mBinding.recycleView.postDelayed(joinChatRoomTask, 5000); -// } -// } - -// @Override -// public void onMessageReceived(List list) { -// if (conversation != null) { -// conversation.markAllMessagesAsRead(); -// } -// -// if (mBinding.recycleView.getVisibility() == View.GONE) { -// return; -// } -// ThreadUtils.runOnUiThread(new Runnable() { -// @Override -// public void run() { -// List items = new ArrayList<>(); -// for (EMMessage item : list) { -// if (item.getChatType() != EMMessage.ChatType.ChatRoom) { -// continue; -// } -// if (toChatUsername != null && !toChatUsername.equals(item.getTo())) { -// continue; -// } -// //如果房间id不对应,则不接收 -// String roomId = item.getStringAttribute("room_id", ""); -// if (!TextUtils.isEmpty(roomId) && !roomId.equals(roomInfoResp.getRoom_info().getRoom_id())) { -// continue; -// } -// int type = item.getIntAttribute("type", 0); -// if (type > 6000 && type < 7000) { //屏蔽6000-7000之外的数据 -// if (type == 6001 && item.getStringAttribute("user_id", "").equals(SpUtils.getUserId())) {//屏蔽自己加入房间消息 -// continue; -// } -// if (type == 6010 && item.getStringAttribute("user_id", "").equals(SpUtils.getUserId())) {//屏蔽自己发送的表情消息 -// continue; -// } -// if (type == 6012 && item.getStringAttribute("user_id", "").equals(SpUtils.getUserId())) {//屏蔽自己发送的文本消息 -// continue; -// } -// items.add(new EMMessageInfo(item)); -// } -// } -// easeChatAdapter.addData(items); -// if (easeChatAdapter.getItemCount() > 1000) { -// easeChatAdapter.clearSomeData(); -// } -// if (isBottom) { -// count = 0; -// refreshSelectLast(); -// } else if (items.size() > 0) { -// count += items.size(); -// if (roomInfoResp.getRoom_info().getChat_status() == 1) { -// if (mBinding.tvCount != null) { -// mBinding.tvCount.setVisibility(View.VISIBLE); -// mBinding.tvCount.setText(count + "条新消息"); -// } -// } -// } -// } -// }); -// } - - - /** - * 用户进入房间 - * - * @param roomUserJoinModel - */ -// @Subscribe(sticky = true, threadMode = ThreadMode.MAIN) -// public void subscribeMessages(RoomUserJoinModel roomUserJoinModel) { -// mBinding.wav.addAnim(roomUserJoinModel); -// EventBus.getDefault().removeStickyEvent(roomUserJoinModel); -// } - - /** - * 关闭公屏 - */ -// @Subscribe(threadMode = ThreadMode.MAIN) -// public void subscribeMessages(ClosePublicScreenEvent closePublicScreenEvent) { -// mBinding.tvClose.setVisibility(View.VISIBLE); -// mBinding.llHeadTab.setVisibility(View.GONE); -// mBinding.recycleView.setVisibility(View.GONE);//隐藏消息列表 -// mBinding.tvCount.setVisibility(View.GONE);//隐藏未读消息数 -// count = 0;//未读消息数清零 -// isBottom = true; -// MvpPre.switchPublicScreen(roomInfoResp.getRoom_info().getRoom_id(), "0"); -// } - - /** - * 开启公屏 - */ -// @Subscribe(threadMode = ThreadMode.MAIN) -// public void subscribeMessages(OpenPublicScreenEvent openPublicScreenEvent) { -// count = 0;//未读消息数清零 -// isBottom = true; -// //如果有数据或者recycle view有item view就删除;否则程序崩溃,找不到item -// if (mBinding.recycleView.getChildCount() > 0) { -// mBinding.recycleView.removeAllViews(); -// easeChatAdapter.clearData(); -// } -// mBinding.recycleView.setVisibility(View.VISIBLE);//开启消息列表 -// mBinding.tvClose.setVisibility(View.GONE); -// mBinding.llHeadTab.setVisibility(View.VISIBLE); -// MvpPre.switchPublicScreen(roomInfoResp.getRoom_info().getRoom_id(), "1"); -// } - - /** - * 开关公屏 1开2关 - *

- * // * @param event - */ -// @Subscribe(threadMode = ThreadMode.MAIN) -// public void subscribeMessages(PublicScreenEvent event) { -// if (roomInfoResp.getRoom_info().getRoom_id().equals(event.getRoom_id())) { -// roomInfoResp.getRoom_info().setChat_status(event.getStatus()); -// setUpPublicScreen(); -// } -// } - private void refreshSelectLast() { - if (mBinding.recycleViewPublic != null) { - mBinding.recycleViewPublic.scrollToPosition(easeChatAdapter.getItemCount() - 1); - } - } - - /** - * 特效设置 - */ -// @Subscribe(threadMode = ThreadMode.MAIN) -// public void setEffectSwitch(EffectEvent event) { -// if (event.isEffectOn()) {//特效开启 -// if (!mBinding.wav.animEnded) { -// mBinding.wav.setVisibility(View.VISIBLE); -// } -// } else { -// mBinding.wav.closeEffect(); -// mBinding.wav.setVisibility(View.GONE); -// } -// } - - /** - * 浇水礼物推送 - */ -// @Subscribe(threadMode = ThreadMode.MAIN) -// public void setSwitcher(LuckyRankListBean listBean) { -// if (listBean != null) { -//// oldList = listBean; -// initSwitcher(listBean); -// } -// } - - /** - * 推送区域 - */ -// public void onSwitcher(View view) { -// recordDialogFragment = RoomWinningRecordDialogFragment.newInstance(); -// if (recordDialogFragment != null -// && recordDialogFragment.getDialog() != null -// && recordDialogFragment.getDialog().isShowing() -// && !recordDialogFragment.isRemoving()) { -// //dialog is showing so do something -// } else { -// recordDialogFragment.show((getActivity()).getSupportFragmentManager(), "RoomWaterTreeRankDialog"); -// //dialog is not showing -// } -// AppLogUtil.reportAppLog(AppLogEvent.D010604); -// } - -// @Override -// public void onConnected() { -// onChatRoomViewCreation(); -// } - -// @Override -// public void onDisconnected(int i) { -// Logger.e("onDisconnected", i); -// } - - - /** - * 重连任务 - */ -// private Runnable joinChatRoomTask = new Runnable() { -// @Override -// public void run() { -// onChatRoomViewCreation(); -// } -// }; - -// @Override -// public void onResume() { -// super.onResume(); -// if (mBinding.vfSwitcher != null) { -// mBinding.vfSwitcher.startFlipping(); -// } -// } - -// @Override -// public void onPause() { -// super.onPause(); -// if (mBinding.vfSwitcher != null) { -// mBinding.vfSwitcher.stopFlipping(); -// } -// } } + diff --git a/moduleroom/src/main/java/com/example/moduleroom/fragment/SingSongFragment.java b/moduleroom/src/main/java/com/example/moduleroom/fragment/SingSongFragment.java index 4d9098c1..273d049e 100644 --- a/moduleroom/src/main/java/com/example/moduleroom/fragment/SingSongFragment.java +++ b/moduleroom/src/main/java/com/example/moduleroom/fragment/SingSongFragment.java @@ -1349,6 +1349,7 @@ public class SingSongFragment extends BaseRoomFragment @@ -78,7 +78,6 @@ android:layout_width="0dp" android:layout_weight="1" android:layout_height="match_parent" - android:layout_marginEnd="@dimen/dp_4" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" android:background="@mipmap/pk_left" @@ -119,6 +118,7 @@ android:id="@+id/cl_right" android:layout_width="0dp" android:layout_weight="1" + android:layout_marginStart="@dimen/dp_3" android:layout_height="match_parent" app:layout_constraintStart_toEndOf="@+id/cl_left" app:layout_constraintTop_toTopOf="parent" diff --git a/moduleroom/src/main/res/layout/item_emotion.xml b/moduleroom/src/main/res/layout/item_emotion.xml index 40de97b4..dc01fa7c 100644 --- a/moduleroom/src/main/res/layout/item_emotion.xml +++ b/moduleroom/src/main/res/layout/item_emotion.xml @@ -1,10 +1,10 @@ + > + + diff --git a/moduleroom/src/main/res/layout/item_noble_piaoping.xml b/moduleroom/src/main/res/layout/item_noble_piaoping.xml new file mode 100644 index 00000000..bb1031af --- /dev/null +++ b/moduleroom/src/main/res/layout/item_noble_piaoping.xml @@ -0,0 +1,34 @@ + + + + + + + + + \ No newline at end of file diff --git a/moduleroom/src/main/res/layout/room_top.xml b/moduleroom/src/main/res/layout/room_top.xml index 5c8f540a..256f797e 100644 --- a/moduleroom/src/main/res/layout/room_top.xml +++ b/moduleroom/src/main/res/layout/room_top.xml @@ -108,7 +108,8 @@ android:gravity="center" android:text="0" android:textColor="@color/white" - android:textSize="@dimen/sp_12" /> + android:textSize="@dimen/sp_12" + android:visibility="gone"/> - + + android:allowBackup="true" + android:icon="@mipmap/ic_launcher" + android:roundIcon="@mipmap/ic_launcher_round" + android:supportsRtl="true" + android:theme="@style/BaseAppTheme"> + android:name=".activity.NoblePaymentActivity" + android:exported="false"/> + android:name=".activity.NobleDetailsActivity" + android:exported="false"/> + android:name=".activity.NobleTitleActivity" + android:exported="false"/> + android:name=".activity.GiftWallActivity" + android:exported="false"/> + android:name=".activity.AboutUsActivity" + android:exported="false"/> + android:name=".activity.WithdrawalListActivity" + android:exported="false"/> + android:name=".activity.GiftBoxRecordActivity" + android:exported="false"/> + android:name=".activity.BindCardDetailsActivity" + android:exported="false"/> + android:name=".activity.BindCardActivity" + android:exported="false"/> + android:name=".activity.AlbumDetailActivity" + android:exported="false"/> + android:name=".activity.SettingActivity" + android:exported="false"/> + android:name=".activity.CreateAlbumActivity" + android:exported="false"/> + android:name=".activity.RevenueActivity" + android:exported="false"/> + android:name=".activity.DailyTasksActivity" + android:exported="false"/> + android:name=".activity.UserHomepageActivity" + android:exported="false"/> + android:name=".activity.MyBagActivity" + android:exported="false"/> + android:name=".activity.BriefIntroductionActivity" + android:exported="false"/> + android:name=".activity.ChangeNicknameActivity" + android:exported="false"/> + android:name=".activity.CurrencyExchangeActivity" + android:exported="false"/> + android:name=".activity.WithdrawalActivity" + android:exported="false"/> + android:name=".activity.RechargeActivity" + android:exported="false"/> + android:name=".activity.MyMoneyActivity" + android:exported="false"/> + android:name=".activity.EditUserInfoActivity" + android:exported="false"/> + android:name=".activity.ChangPassActivity" + android:exported="false"/> + android:name=".activity.PersonalityActivity" + android:exported="false"/> + android:name=".activity.RealDetailActivity" + android:exported="false"/> + android:name=".activity.RoomAllowanceDetailActivity" + android:exported="false"/> + android:name=".activity.RoomAllowanceActivity" + android:exported="false"/> + android:name=".activity.RoomDetailsActivity" + android:exported="false"/> + android:name=".activity.CreatedRoomActivity" + android:exported="false"/> + android:name=".activity.MyRoomActivity" + android:exported="false"/> + android:name=".activity.PhoneReplacementActivity" + android:exported="false"/> + android:name=".activity.BlacklistActivity" + android:exported="false"/> + android:name=".activity.MessageReminderActivity" + android:exported="false"/> + android:name=".activity.NotificationActivity" + android:exported="false"/> + + \ No newline at end of file diff --git a/modulevocal/src/main/java/com/example/modulevocal/activity/GiftWallActivity.java b/modulevocal/src/main/java/com/example/modulevocal/activity/GiftWallActivity.java new file mode 100644 index 00000000..89cbc444 --- /dev/null +++ b/modulevocal/src/main/java/com/example/modulevocal/activity/GiftWallActivity.java @@ -0,0 +1,93 @@ +package com.example.modulevocal.activity; + +import android.annotation.SuppressLint; +import android.graphics.Color; +import android.util.TypedValue; +import android.view.View; +import android.widget.TextView; +import androidx.viewpager2.widget.ViewPager2; +import com.example.modulevocal.R; +import com.example.modulevocal.activity.ui.main.GiftWallConacts; +import com.example.modulevocal.activity.ui.main.GiftWallPresenter; +import com.google.android.material.tabs.TabLayout; +import androidx.viewpager.widget.ViewPager; +import com.example.modulevocal.activity.ui.main.SectionsPagerAdapter; +import com.example.modulevocal.databinding.ActivityGiftWallBinding; +import com.google.android.material.tabs.TabLayoutMediator; +import com.xscm.moduleutil.activity.BaseMvpActivity; +import com.xscm.moduleutil.bean.CombinedGiftBean; +import com.xscm.moduleutil.bean.GiftUserWallBean; +import com.xscm.moduleutil.bean.RoomTypeModel; +import com.xscm.moduleutil.utils.SpUtil; + +/** + * 礼物墙 + */ +public class GiftWallActivity extends BaseMvpActivity implements GiftWallConacts.View { + SectionsPagerAdapter sectionsPagerAdapter; + + @Override + protected void initData() { + mBinding.topBar.setTitle("礼物墙"); + mBinding.topBar.setColor(getResources().getColor(R.color.white)); + MvpPre.giftWall(SpUtil.getUserId()+""); + } + + // 在获取到数据后调用此方法初始化 ViewPager + private void setupViewPagerWithData(GiftUserWallBean data) { + sectionsPagerAdapter = new SectionsPagerAdapter(this, data); + ViewPager2 viewPager = mBinding.viewPager; + viewPager.setAdapter(sectionsPagerAdapter); + TabLayout tabs = mBinding.tabs; + + // TabLayout 需要手动关联 + new TabLayoutMediator(mBinding.tabs, mBinding.viewPager, + (tab, position) -> tab.setText(sectionsPagerAdapter.getPageTitle(position)) + ).attach(); + + // 设置选中和未选中的文字颜色及大小 + tabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { + @Override + public void onTabSelected(TabLayout.Tab tab) { + View customView = tab.getCustomView(); + if (customView instanceof TextView textView) { + textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16); + textView.setTextColor(getResources().getColor(android.R.color.white)); + customView.setBackgroundResource(com.xscm.moduleutil.R.drawable.tab_indicator); + } + } + + @Override + public void onTabUnselected(TabLayout.Tab tab) { + View customView = tab.getCustomView(); + if (customView instanceof TextView textView) { + textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14); + textView.setTextColor(Color.parseColor("#ffffff")); + customView.setBackgroundResource(com.xscm.moduleutil.R.drawable.tab_unselected_background); + } + } + + @Override + public void onTabReselected(TabLayout.Tab tab) { + } + }); + tabs.selectTab(tabs.getTabAt(0)); + } + + @Override + protected int getLayoutId() { + return R.layout.activity_gift_wall; + } + + @Override + protected GiftWallPresenter bindPresenter() { + return new GiftWallPresenter(this, this); + } + + @Override + public void setGiftWall(GiftUserWallBean data) { + // 添加点亮的礼物 + // 初始化 ViewPager 和 TabLayout + setupViewPagerWithData(data); + } +} \ No newline at end of file diff --git a/modulevocal/src/main/java/com/example/modulevocal/activity/NobleDetailsActivity.java b/modulevocal/src/main/java/com/example/modulevocal/activity/NobleDetailsActivity.java new file mode 100644 index 00000000..35407de7 --- /dev/null +++ b/modulevocal/src/main/java/com/example/modulevocal/activity/NobleDetailsActivity.java @@ -0,0 +1,202 @@ +package com.example.modulevocal.activity; + +import android.annotation.SuppressLint; +import android.content.Intent; +import android.graphics.LinearGradient; +import android.graphics.Shader; +import android.os.Build; +import android.os.Bundle; + +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewTreeObserver; +import android.widget.GridView; +import android.widget.TextView; +import androidx.activity.EdgeToEdge; +import androidx.annotation.RequiresApi; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.graphics.Insets; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; +import androidx.viewpager2.widget.ViewPager2; +import com.example.modulevocal.R; +import com.example.modulevocal.adapter.GridNobleAdapter; +import com.example.modulevocal.adapter.NobliityBannerAdapter; +import com.example.modulevocal.conacts.NobleTitleConacts; +import com.example.modulevocal.databinding.ActivityNobleDetailsBinding; +import com.example.modulevocal.presenter.NobleTitlePresenter; +import com.xscm.moduleutil.activity.BaseMvpActivity; +import com.xscm.moduleutil.base.CommonAppContext; +import com.xscm.moduleutil.bean.*; +import com.xscm.moduleutil.dialog.RoomAuctionWebViewDialog; +import com.zhpan.bannerview.BannerViewPager; +import com.zhpan.bannerview.constants.PageStyle; + +import java.util.List; + +import static android.view.View.GONE; + +/** + * @Description: 这是爵位详情方案 + * @Author: qx + * @CreateDate: 2022/3/23 10:05 + */ +public class NobleDetailsActivity extends BaseMvpActivity implements NobleTitleConacts.View { + NobliityBannerAdapter mAdapter; + GridView gridView; + GridNobleAdapter mGiftWallAdapter; + + private String lid=""; + + @Override + protected void initView() { + super.initView(); + mBinding.ivBack.setColorFilter(getResources().getColor(R.color.white)); + mBinding.ivBack.setOnClickListener(v -> finish()); + mBinding.ivIntent.setOnClickListener(v -> {//爵位规则 + Bundle bundle = new Bundle(); + bundle.putString("url", CommonAppContext.getInstance().getCurrentEnvironment().getServerUrl() + "api/Page/page_show?id=29"); + RoomAuctionWebViewDialog dialog = new RoomAuctionWebViewDialog(this, bundle); + dialog.show(); + }); + gridView = mBinding.gridView; + mGiftWallAdapter=new GridNobleAdapter(); + mBinding.imLjkt.setOnClickListener(v -> { + Intent intent = new Intent(this, NoblePaymentActivity.class); + Bundle bundle = new Bundle(); + bundle.putString("lid",lid); + intent.putExtras( bundle); + startActivity(intent); + }); + } + + @Override + protected void initData() { + lid=getIntent().getStringExtra("lid"); + if (lid==null){ + lid=""; + } + MvpPre.getNobilityList(); + } + + @Override + protected int getLayoutId() { + return R.layout.activity_noble_details; + } + + @Override + protected NobleTitlePresenter bindPresenter() { + return new NobleTitlePresenter(this, this); + } + + @Override + public void getNobilityDetail(NobilitDeatils nobilitDeatils) { + + } + int index = 0; + @RequiresApi(api = Build.VERSION_CODES.O) + @Override + public void getNobilityList(List nobilitLists) { + if (nobilitLists==null){ + return; + } + + + for (int i=0; i < nobilitLists.size(); i++){ + if (lid.equals(nobilitLists.get(i).getLid()+"")){ + index = i; + } + } + + mAdapter = new NobliityBannerAdapter(); + mBinding.banner + .setAdapter(mAdapter) + .setAutoPlay(false) + .setIndicatorVisibility(GONE) + .setPageStyle(PageStyle.MULTI_PAGE_OVERLAP, 0.6f) + .setRevealWidth(200) + .setCanLoop(false) + .create(); + mBinding.banner.create(nobilitLists); // 刷新数据并启动自动播放 + mBinding.banner.setCurrentItem(index); + mAdapter.setmCurrentPosition( index); + mBinding.banner.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + super.onPageScrolled(position, positionOffset, positionOffsetPixels); + updateNobleInfo(nobilitLists.get( position), position); + } + + @Override + public void onPageSelected(int position) { + super.onPageSelected(position); + } + + @Override + public void onPageScrollStateChanged(int state) { + super.onPageScrollStateChanged(state); + } + }); + updateNobleInfo(nobilitLists.get(index), index); + } + + @Override + public void bindType(BindType bindType) { + + } + + @Override + public void appPay(AppPay appPay) { + + } + + @Override + public void getNobilityPrice(NobilityPrice nobilityPrice) { + + } + + @SuppressLint("SetTextI18n") + private void updateNobleInfo(NobilitList nobilitLists, int position) { + mBinding.tvNobleLv.setText(nobilitLists.getName()); + applyGradientToTextView(mBinding.tvNobleLv); + mBinding.tvTq.setText("专属特权(" + nobilitLists.getPower().getCount_str()+")"); + mBinding.tvLvTis.setText(nobilitLists.getName() + "专属 ¥"); + mBinding.tvNobleMob.setText(nobilitLists.getPay_price()+" / "+nobilitLists.getDay()+"天"); + + gridView.setAdapter(mGiftWallAdapter); + lid=nobilitLists.getLid()+""; + // 观察数据变化并更新 GridView + mGiftWallAdapter.updateData(nobilitLists.getPower().getList()); + if (position>=index){ + if (position==index){ + mBinding.imLjkt.setImageResource(com.xscm.moduleutil.R.mipmap.noble_xf); + }else { + mBinding.imLjkt.setImageResource(com.xscm.moduleutil.R.mipmap.noble_ljsj); + } + mBinding.imLjkt.setClickable( true); + }else { + mBinding.imLjkt.setImageResource(com.xscm.moduleutil.R.mipmap.noble_h_kt); + mBinding.imLjkt.setClickable( false); + } + } + private void applyGradientToTextView(TextView textView) { + ViewTreeObserver vto = textView.getViewTreeObserver(); + vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + textView.getViewTreeObserver().removeOnGlobalLayoutListener(this); + int width = textView.getWidth(); + if (width > 0) { + LinearGradient gradient = new LinearGradient( + 0, 0, width, 0, + new int[]{0xFFF4C07C, 0xFFFFFFFF, 0xFFF4C07C}, + new float[]{0f, 0.5f, 1f}, + Shader.TileMode.CLAMP + ); + textView.getPaint().setShader(gradient); + textView.invalidate(); + } + } + }); + } +} \ No newline at end of file diff --git a/modulevocal/src/main/java/com/example/modulevocal/activity/NoblePaymentActivity.java b/modulevocal/src/main/java/com/example/modulevocal/activity/NoblePaymentActivity.java new file mode 100644 index 00000000..20a7636f --- /dev/null +++ b/modulevocal/src/main/java/com/example/modulevocal/activity/NoblePaymentActivity.java @@ -0,0 +1,274 @@ +package com.example.modulevocal.activity; + +import android.content.Intent; +import android.graphics.Paint; +import android.net.Uri; +import android.os.Bundle; + +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import androidx.activity.EdgeToEdge; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.graphics.Insets; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; +import androidx.recyclerview.widget.LinearLayoutManager; +import com.alibaba.android.arouter.launcher.ARouter; +import com.alibaba.fastjson.JSON; +import com.example.modulevocal.R; +import com.example.modulevocal.adapter.NoblePrivilegeAdapter; +import com.example.modulevocal.conacts.NobleTitleConacts; +import com.example.modulevocal.databinding.ActivityNoblePaymentBinding; +import com.example.modulevocal.presenter.NobleTitlePresenter; +import com.hjq.toast.ToastUtils; +import com.tencent.mm.opensdk.openapi.IWXAPI; +import com.tencent.mm.opensdk.openapi.WXAPIFactory; +import com.xscm.moduleutil.activity.BaseMvpActivity; +import com.xscm.moduleutil.adapter.PayMethodAdapter; +import com.xscm.moduleutil.base.CommonAppContext; +import com.xscm.moduleutil.bean.*; +import com.xscm.moduleutil.color.ThemeableDrawableUtils; +import com.xscm.moduleutil.dialog.RoomAuctionWebViewDialog; +import com.xscm.moduleutil.event.PayEvent; +import com.xscm.moduleutil.utils.*; +import com.xscm.moduleutil.widget.PaymentUtil; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; + +import java.lang.reflect.Field; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import static android.view.View.GONE; +import static android.view.View.VISIBLE; + +/** + * @Description: 这是爵位支付方案 + * @Author: qx + * @CreateDate: 2022/3/23 10:05 + */ +public class NoblePaymentActivity extends BaseMvpActivity implements NobleTitleConacts.View{ + private PayMethodAdapter bindTypeAdapter; + private BindType.AllData selectedItem; + private String lid; + private String money; + private String name; + private String yxq; + private String imNoble2; + private List powerItems=new ArrayList<>(); + @Override + protected void initData() { + mBinding.ivBack.setOnClickListener(v -> finish()); + mBinding.ivIntent.setOnClickListener(v -> {//爵位规则 + Bundle bundle = new Bundle(); + bundle.putString("url", CommonAppContext.getInstance().getCurrentEnvironment().getServerUrl() + "api/Page/page_show?id=29"); + RoomAuctionWebViewDialog dialog = new RoomAuctionWebViewDialog(this, bundle); + dialog.show(); }); + + mBinding.tvYsxy.setOnClickListener(this::onClick); + + mBinding.recycleView1.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)); + bindTypeAdapter = new PayMethodAdapter(com.xscm.moduleutil.R.layout.item_bind_type); + mBinding.recycleView1.setAdapter(bindTypeAdapter); + + bindTypeAdapter.setOnItemClickListener((adapter, view, position) -> { + + bindTypeAdapter.setSelectedPosition(position); + + // 获取当前选中的数据 + selectedItem = bindTypeAdapter.getItem(position); + // 可以在这里处理选中逻辑,比如保存到变量或触发支付 + }); + + + ThemeableDrawableUtils.setThemeableRoundedBackground(mBinding.tvPayment, ColorManager.getInstance().getPrimaryColorInt(), 53); + mBinding.tvPayment.setTextColor(ColorManager.getInstance().getButtonColorInt()); + + mBinding.tvPayment.setOnClickListener(this::onClick); + + } + + @Override + protected void onResume() { + super.onResume(); + lid=getIntent().getStringExtra("lid"); + MvpPre.getNobilityPrice(lid); + MvpPre.bindType(SpUtil.getUserId() + ""); + } + + private void onClick(View view) { + int id = view.getId(); + if (id== R.id.tv_ysxy) { + ARouter.getInstance().build(ARouteConstants.H5).withString("url", CommonAppContext.getInstance().getCurrentEnvironment().getServerUrl()+"/api/Page/page_show?id=30").withString("title", "爵位服务协议").navigation(); + }else if (id== R.id.tv_payment){ + if (!mBinding.cbPrivacy.isChecked()) { + ToastUtils.show("请先勾选服务条款"); + return; + } + MvpPre.appPay(SpUtil.getUserId() + "", money, selectedItem.getType(),lid); + } + } + + @Override + protected int getLayoutId() { + return R.layout.activity_noble_payment; + } + + @Override + protected NobleTitlePresenter bindPresenter() { + return new NobleTitlePresenter(this, this); + } + + @Override + public void getNobilityDetail(NobilitDeatils nobilitDeatils) { + + } + + @Override + public void getNobilityList(List nobilitLists) { + + } + + @Override + public void bindType(BindType bindType) { + List allData = new ArrayList<>(); + if (bindType.getAli().getIs_pay_open().equals("1")) { + allData.add(bindType.getAli()); + } + if (bindType.getWx().getIs_pay_open().equals("1")) { + allData.add(bindType.getWx()); + } + if (bindType.getBank().getIs_pay_open().equals("1")) { + allData.add(bindType.getBank()); + } + if (bindType.getAli_tl().getIs_pay_open().equals("1")) { + allData.add(bindType.getAli_tl()); + } + if (bindType.getWx_tl().getIs_pay_open().equals("1")) { + allData.add(bindType.getWx_tl()); + } + + bindTypeAdapter.setNewData(allData); + } + + @Override + public void appPay(AppPay appPay) { + if (appPay.getAli()!=null) { + PaymentUtil.payAlipay(this, appPay.getAli()); + }else if (appPay.getWx()!=null){ + + IWXAPI wxapi = WXAPIFactory.createWXAPI(this, CommonAppContext.getInstance().getCurrentEnvironment().getWxAppId()); + PaymentUtil.payWxMiniProgram2(wxapi,appPay); + }else if (appPay.getTl()!=null){ + if (appPay.getTl().getRemark().equals("5")) {//微信 + IWXAPI wxapi = WXAPIFactory.createWXAPI(this, CommonAppContext.getInstance().getCurrentEnvironment().getWxAppId()); + try { + String paramString = buildParamString(appPay.getTl()); + PaymentUtil.payWxMiniProgramWx(wxapi,paramString); + android.util.Log.d("RequestParams", paramString); // 输出拼接后的参数 + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } else if (appPay.getTl().getRemark().equals("4")) {//支付宝 + String s= JSON.toJSONString(appPay.getTl()); + try { + String query = URLEncoder.encode("payinfo=" + URLEncoder.encode(s, "UTF-8"), "UTF-8"); + String url = "alipays://platformapi/startapp?appId=2021001104615521&page=pages/orderDetail/orderDetail&thirdPartSchema=" + + URLEncoder.encode("myziroom://myziroom/", "UTF-8") + "&query=" + query; + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); + startActivity(intent); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + } + + @Override + public void getNobilityPrice(NobilityPrice nobilityPrice) { + if (nobilityPrice==null){ + return; + } + name=nobilityPrice.getNobility_name(); + yxq=nobilityPrice.getEnd_time(); + mBinding.tvLv.setText(nobilityPrice.getNobility_name()); + ImageUtils.loadHeadCC(nobilityPrice.getNobility_image(), mBinding.imNoble); + imNoble2=nobilityPrice.getNobility_image(); + mBinding.tvTime.setText("有效期:"+nobilityPrice.getDay()+"天"); + mBinding.tvSjJg.setText("¥"+nobilityPrice.getPrice()); + mBinding.tvHxJg.setText("¥"+nobilityPrice.getPay_price()); + mBinding.tvHxJg.setPaintFlags( mBinding.tvHxJg.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); + money=nobilityPrice.getPrice(); + + NoblePrivilegeAdapter adapter = new NoblePrivilegeAdapter(); + adapter.setNewData(nobilityPrice.getPower_list()); + mBinding.recycleView2.setLayoutManager(new LinearLayoutManager(this)); + // 设置到 RecyclerView + mBinding.recycleView2.setAdapter(adapter); + powerItems=nobilityPrice.getPower_list(); + + } + + public static String buildParamString(Object obj) throws IllegalAccessException { + Class clazz = obj.getClass(); + Field[] fields = clazz.getDeclaredFields(); + TreeMap paramMap = new TreeMap<>(); + + // 遍历字段并填充 TreeMap + for (Field field : fields) { + field.setAccessible(true); // 允许访问私有字段 + Object value = field.get(obj); + if (value != null && !String.valueOf(value).isEmpty()) { + paramMap.put(field.getName(), String.valueOf(value)); + } + } + + // 使用 StringBuilder 拼接参数字符串 + StringBuilder builder = new StringBuilder(); + for (Map.Entry entry : paramMap.entrySet()) { + if (builder.length() > 0) { + builder.append("&"); + } + builder.append(entry.getKey()) + .append("=") + .append(entry.getValue()); + } + + return builder.toString(); + } + + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(PayEvent event) { + if (event.getType()==1){ + ToastUtils.show("支付成功"); + mBinding.cl.setVisibility(GONE); + mBinding.imNoble.setVisibility(GONE); + mBinding.t2.setVisibility(GONE); + mBinding.recycleView1.setVisibility(GONE); + mBinding.tvPayment.setVisibility(GONE); + mBinding.llAgreement.setVisibility(GONE); + mBinding.recycleView2.setVisibility(GONE); + mBinding.tvTs.setVisibility(GONE); + mBinding.tv.setVisibility(GONE); + + mBinding.cl2.setVisibility(VISIBLE); + mBinding.tvSucess2.setText("恭喜您已成功开通"+name+"爵位"); + mBinding.tv3.setText(name+"特权"); + mBinding.tv4.setText("有效期:"+yxq); + mBinding.tvPayment2.setOnClickListener(v -> { + finish(); + }); + ImageUtils.loadHeadCC(imNoble2, mBinding.imNoble2); + NoblePrivilegeAdapter adapter = new NoblePrivilegeAdapter(); + adapter.setNewData(powerItems); + mBinding.recycleView3.setLayoutManager(new LinearLayoutManager(this)); + // 设置到 RecyclerView + mBinding.recycleView3.setAdapter(adapter); + } + } +} \ No newline at end of file diff --git a/modulevocal/src/main/java/com/example/modulevocal/activity/NobleTitleActivity.java b/modulevocal/src/main/java/com/example/modulevocal/activity/NobleTitleActivity.java new file mode 100644 index 00000000..6380ea78 --- /dev/null +++ b/modulevocal/src/main/java/com/example/modulevocal/activity/NobleTitleActivity.java @@ -0,0 +1,288 @@ +package com.example.modulevocal.activity; + +import android.annotation.SuppressLint; +import android.content.Intent; +import android.graphics.LinearGradient; +import android.graphics.Shader; +import android.os.Bundle; + +import android.os.Handler; +import android.util.Log; +import android.view.View; +import android.view.ViewTreeObserver; +import android.widget.HorizontalScrollView; +import android.widget.LinearLayout; +import android.widget.TextView; +import androidx.activity.EdgeToEdge; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.graphics.Insets; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; +import com.alibaba.android.arouter.launcher.ARouter; +import com.example.modulevocal.R; +import com.example.modulevocal.conacts.NobleTitleConacts; +import com.example.modulevocal.databinding.ActivityNobleTitleBinding; +import com.example.modulevocal.presenter.NobleTitlePresenter; +import com.rmondjone.locktableview.LockTableView; +import com.rmondjone.xrecyclerview.ProgressStyle; +import com.rmondjone.xrecyclerview.XRecyclerView; +import com.xscm.moduleutil.activity.BaseMvpActivity; +import com.xscm.moduleutil.activity.IPresenter; +import com.xscm.moduleutil.base.BaseRoomContacts; +import com.xscm.moduleutil.base.CommonAppContext; +import com.xscm.moduleutil.bean.*; +import com.xscm.moduleutil.dialog.RoomAuctionWebViewDialog; +import com.xscm.moduleutil.utils.ARouteConstants; +import com.xscm.moduleutil.utils.ImageUtils; +import com.xscm.moduleutil.utils.TimeUtils; + +import java.util.ArrayList; +import java.util.List; + +import static android.view.View.GONE; +import static android.view.View.VISIBLE; + +/** + * @Description: 爵位展示页面 + * @Author: qx + * @Data: 2022/4/18 21:05 + */ +public class NobleTitleActivity extends BaseMvpActivity implements NobleTitleConacts.View { + private LinearLayout mContentView; + private List mNobilityPowerItemList = new ArrayList<>(); + private String lid; + @Override + protected void initData() { + MvpPre.getNobilityDetail(); + } + + @Override + protected void initView() { + super.initView(); + mBinding.ivBack.setColorFilter(getResources().getColor(R.color.white)); + mBinding.ivBack.setOnClickListener(v -> finish()); + mBinding.ivIntent.setOnClickListener(v -> {//爵位规则 + Bundle bundle = new Bundle(); + bundle.putString("url", CommonAppContext.getInstance().getCurrentEnvironment().getServerUrl() + "api/Page/page_show?id=29"); + RoomAuctionWebViewDialog dialog = new RoomAuctionWebViewDialog(this, bundle); + dialog.show(); }); + mContentView = mBinding.contentView; + + mBinding.imMeNobleStatus.setOnClickListener(this::onClick); + mBinding.imMeNobleXf.setOnClickListener(this::onClick); + mBinding.imSj.setOnClickListener(this::onClick); + } + + private void onClick(View view) { + int id = view.getId(); + if (id== R.id.im_me_noble_status || id== R.id.im_sj) { + Intent intent = new Intent(this, NobleDetailsActivity.class); + Bundle bundle = new Bundle(); + bundle.putString("lid",lid); + intent.putExtras( bundle); + startActivity(intent); + }else if (id== R.id.im_me_noble_xf) { + Intent intent = new Intent(this, NoblePaymentActivity.class); + Bundle bundle = new Bundle(); + bundle.putString("lid",lid); + intent.putExtras( bundle); + startActivity(intent); + } + } + + @Override + protected int getLayoutId() { + return R.layout.activity_noble_title; + } + + @Override + protected NobleTitlePresenter bindPresenter() { + return new NobleTitlePresenter(this, this); + } + + private void setmContentView() { + ArrayList> mTableDatas = new ArrayList>(); + ArrayList mfristData = new ArrayList(); + for (int i = 0; i < mNobilityPowerItemList.size(); i++) { + TableCellData mTableCellData = new TableCellData(); + mTableCellData.setTitle(mNobilityPowerItemList.get(i).getName()); + mTableCellData.setColor(""); + mfristData.add(mTableCellData); // 添加各爵位名称 + } + mTableDatas.add(mfristData); // 只添加一次表头 + + // 构建每一行的数据 + if (!mNobilityPowerItemList.isEmpty()) { + int maxPrivileges = mNobilityPowerItemList.get(0).getNobility_list().size(); + + // 为每个特权构建一行数据 + for (int j = 0; j < maxPrivileges; j++) { + ArrayList mRowDatas = new ArrayList(); + + // 添加特权名称(第一列) + if (j < mNobilityPowerItemList.get(0).getNobility_list().size()) { + TableCellData mTableCellData = new TableCellData(); + mTableCellData.setTitle(mNobilityPowerItemList.get(0).getNobility_list().get(j).getName()); + mTableCellData.setColor(""); + mRowDatas.add(mTableCellData); + } else { + mRowDatas.add(new TableCellData()); // 空白占位 + } + + // 添加各个爵位对该特权的支持情况 + for (int i = 1; i < mNobilityPowerItemList.size(); i++) { + if (j < mNobilityPowerItemList.get(i).getNobility_list().size()) { + NobilitDeatils.nobilityPowerItem nobilityItem = mNobilityPowerItemList.get(i); + NobilitDeatils.nobilityPowerItem.nobilityPowerItem nobilityList = nobilityItem.getNobility_list().get(j); + + if ( nobilityList.getId()==2) { + if (nobilityItem.getNick_name_color_name() != null && !nobilityItem.getNick_name_color_name().equals("无")) { + TableCellData mTableCellData = new TableCellData(); + mTableCellData.setTitle(nobilityItem.getNick_name_color_name()); + mTableCellData.setColor(nobilityItem.getNick_name_color()); + mRowDatas.add(mTableCellData); // 支持 + } + }else { + // 根据 status 显示是否支持 + if (nobilityList.getStatus() == 1) { + TableCellData mTableCellData = new TableCellData(); + mTableCellData.setTitle("1"); + mTableCellData.setColor(""); + mRowDatas.add(mTableCellData); // 支持 + } else { + TableCellData mTableCellData = new TableCellData(); + mTableCellData.setTitle("0"); + mTableCellData.setColor(""); + mRowDatas.add(mTableCellData); // 不支持 + } + } + } else { + mRowDatas.add(new TableCellData()); // 空白占位 + } + } + mTableDatas.add(mRowDatas); + } + } + + + final LockTableView mLockTableView = new LockTableView(this, mContentView, mTableDatas); + mLockTableView.setLockFristColumn(true) //是否锁定第一列 + .setLockFristRow(true) //是否锁定第一行 + .setMaxColumnWidth(79) //列最大宽度 + .setMinColumnWidth(30) //列最小宽度 + .setColumnWidth(1, 79) //设置指定列文本宽度 + .setMinRowHeight(30)//行最小高度 + .setMaxRowHeight(35)//行最大高度 + .setTextViewSize(14) //单元格字体大小 + .setFristRowBackGroudColor(com.xscm.moduleutil.R.color.transparent)//表头背景色 + .setTableHeadTextColor(com.xscm.moduleutil.R.color.white)//表头字体颜色 + .setTableContentTextColor(com.xscm.moduleutil.R.color.white)//单元格字体颜色 + .setCellPadding(5)//设置单元格内边距(dp) +// .setNullableString("N/A") //空值替换值 + .setTableViewListener(new LockTableView.OnTableViewListener() { + @Override + public void onTableViewScrollChange(int x, int y) { +// Log.e("滚动值","["+x+"]"+"["+y+"]"); + } + })//设置横向滚动回调监听 + .setTableViewRangeListener(new LockTableView.OnTableViewRangeListener() { + @Override + public void onLeft(HorizontalScrollView view) { + Log.e("滚动边界", "滚动到最左边"); + } + + @Override + public void onRight(HorizontalScrollView view) { + Log.e("滚动边界", "滚动到最右边"); + } + })//设置横向滚动边界监听 + .show(); //显示表格,此方法必须调用 + mLockTableView.getTableScrollView().setPullRefreshEnabled(false); + mLockTableView.getTableScrollView().setLoadingMoreEnabled(false); + mLockTableView.getTableScrollView().setRefreshProgressStyle(ProgressStyle.SquareSpin); + } + + @SuppressLint("SetTextI18n") + @Override + public void getNobilityDetail(NobilitDeatils nobilitDeatils) { + ImageUtils.loadHeadCC(nobilitDeatils.getUser_info().getAvatar(), mBinding.ciUserImage); + mBinding.tvUserName.setText(nobilitDeatils.getUser_info().getNickname()); + if (nobilitDeatils.getNobility_info().getStatus() == 0) { + mBinding.tvUserLv.setText("暂未开通任何爵位"); + mBinding.imMeNobleStatus.setImageResource(com.xscm.moduleutil.R.mipmap.me_noble_no); + mBinding.tvUserStatus.setText("您尚未开通任何爵位"); + mBinding.imMeNobleXf.setVisibility(GONE); + mBinding.imSj.setVisibility(GONE); + mBinding.ciImage2.setVisibility(GONE); + mBinding.tvMeX.setVisibility(GONE); + mBinding.imKt.setVisibility(GONE); + } else { + lid=nobilitDeatils.getNobility_info().getLid()+""; + mBinding.tvUserLv.setText("的爵位"); + mBinding.imMeNobleStatus.setVisibility(GONE); + ImageUtils.loadHeadCC(nobilitDeatils.getNobility_info().getImage(), mBinding.imNoble); + mBinding.imMeNobleXf.setVisibility(VISIBLE); + mBinding.tvMeNobleLv.setVisibility(VISIBLE); + mBinding.tvUserStatus.setText("截止时间:" + nobilitDeatils.getNobility_info().getEnd_time()); + mBinding.tvMeNobleLv.setText(nobilitDeatils.getNobility_info().getName()); + applyGradientToTextView(mBinding.tvMeNobleLv); + mBinding.imSj.setVisibility(VISIBLE); + mBinding.ciImage2.setVisibility(VISIBLE); + mBinding.tvMeX.setVisibility(VISIBLE); + mBinding.imKt.setVisibility(VISIBLE); + ImageUtils.loadHeadCC(nobilitDeatils.getUser_info().getAvatar(), mBinding.ciImage2); + String nickname = nobilitDeatils.getUser_info().getNickname(); + String displayNickname = nickname.length() > 3 ? nickname.substring(0, 3) + ".." : nickname; + mBinding.tvMeX.setText(displayNickname + "的当前爵位状态是" + nobilitDeatils.getNobility_info().getName()); +// mBinding.tvMeX.setText(nobilitDeatils.getUser_info().getNickname()+"的当前爵位状态是"+nobilitDeatils.getNobility_info().getName()); + + } + + mNobilityPowerItemList = nobilitDeatils.getNobility_power_list(); + setmContentView(); + } + + @Override + public void getNobilityList(List nobilitLists) { + + } + + @Override + public void bindType(BindType bindType) { + + } + + @Override + public void appPay(AppPay appPay) { + + } + + @Override + public void getNobilityPrice(NobilityPrice nobilityPrice) { + + } + + // 在 Activity 或 Fragment 中 + private void applyGradientToTextView(TextView textView) { + ViewTreeObserver vto = textView.getViewTreeObserver(); + vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + textView.getViewTreeObserver().removeOnGlobalLayoutListener(this); + int width = textView.getWidth(); + int height = textView.getHeight(); + if (width > 0) { + LinearGradient gradient = new LinearGradient( + 0, 0, 0, height, + new int[]{0xFFA292FF,0xFFA292FF, 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, 0xFFA292FF,0xFFA292FF}, + new float[]{0f,0.2f,0.5f, 0.5f,0.5f, 0.8f, 1f} , + Shader.TileMode.MIRROR + ); + textView.getPaint().setShader(gradient); + textView.invalidate(); + } + } + }); + } + +} \ No newline at end of file diff --git a/modulevocal/src/main/java/com/example/modulevocal/activity/SettingActivity.java b/modulevocal/src/main/java/com/example/modulevocal/activity/SettingActivity.java index 4e7d4498..c6dc60db 100644 --- a/modulevocal/src/main/java/com/example/modulevocal/activity/SettingActivity.java +++ b/modulevocal/src/main/java/com/example/modulevocal/activity/SettingActivity.java @@ -21,6 +21,7 @@ import com.xscm.moduleutil.activity.BaseMvpActivity; import com.xscm.moduleutil.activity.WebViewActivity; import com.xscm.moduleutil.base.CommonAppContext; import com.xscm.moduleutil.bean.FirstChargeGiftBean; +import com.xscm.moduleutil.bean.UserInfo; import com.xscm.moduleutil.dialog.FirstChargeDialog; import com.xscm.moduleutil.dialog.RealNameDialog; import com.xscm.moduleutil.dialog.YouthModelDialog; @@ -40,6 +41,7 @@ public class SettingActivity extends BaseMvpActivity mDataList; + + public GiftWallAdapter(List dataList) { + this.mDataList = dataList; + } + + public void updateData(List newDataList) { + this.mDataList = newDataList; + notifyDataSetChanged(); + } + + @Override + public int getCount() { + return mDataList != null ? mDataList.size() : 0; + } + + @Override + public Object getItem(int position) { + return mDataList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + // 实现 GridView item 的布局和数据绑定 + // 这里返回每个 GridView 项的视图 + ViewHolder holder; + if (convertView == null) { + convertView = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_gift_wall, parent, false); + holder = new ViewHolder(); + holder.textView = convertView.findViewById(R.id.tv_gift_name); + holder.iv_gift_image = convertView.findViewById(R.id.iv_gift_image); + holder.gift_num = convertView.findViewById(R.id.gift_num); + holder.tv_price33 = convertView.findViewById(R.id.tv_price33); + holder.rv_gift_user_list = convertView.findViewById(R.id.rv_gift_user_list); + holder.tv_gift_values = convertView.findViewById(R.id.tv_gift_values); + holder.cl_gift_item = convertView.findViewById(R.id.cl_gift_item); + convertView.setTag(holder); + } else { + holder = (ViewHolder) convertView.getTag(); + } + + GiftUserWallBean.GiftWallBean item = mDataList.get(position); + holder.textView.setText(item.getGift_name()); +// ImageUtils.loadHeadCC(item.getBase_image(), holder.iv_gift_image); + holder.tv_price33.setText(item.getGift_price()); + + + TextView tv_number = holder.gift_num; + if (item.is_liang()) { + holder.tv_gift_values.setVisibility(View.VISIBLE); + holder.gift_num.setVisibility(View.VISIBLE); + holder.rv_gift_user_list.setVisibility(View.VISIBLE); + holder.cl_gift_item.setBackgroundResource(com.xscm.moduleutil.R.mipmap.gift_wall_liang); +// helper.getView(R.id.cl_iv_down_on).setBackgroundColor(Color.parseColor("#E6E6E6")); + // 点亮的礼物显示高亮和送礼物的用户 + tv_number.setText("共计" + item.getTotal_count() + "个"); + ImageUtils.loadHeadCC(item.getBase_image(), holder.iv_gift_image); + // 显示送礼物的用户列表 + RecyclerView recyclerView = holder.rv_gift_user_list; +// recyclerView.setLayoutManager(new GridLayoutManager(mContext,2,LinearLayoutManager.HORIZONTAL,false)); +// recyclerView.setLayoutManager(new LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false)); + + recyclerView.setLayoutManager(new LinearLayoutManager(convertView.getContext(), LinearLayoutManager.HORIZONTAL, false) { + @Override + public boolean canScrollHorizontally() { + return false; // 禁止水平滑动 + } + }); + +// TopUsersAdapter topUsersAdapter = new TopUsersAdapter(item.getTop_users()); + if (item.getTop_users() != null && item.getTop_users().size() > 0) { + List displayUsers = new ArrayList<>(); + if (item.getTop_users() != null) { + int maxDisplay = Math.min(2, item.getTop_users().size()); // 最多显示2个 + for (int i = 0; i < maxDisplay; i++) { + displayUsers.add(item.getTop_users().get(i)); + } + } + TopUsersAdapter topUsersAdapter = new TopUsersAdapter(displayUsers); + recyclerView.setAdapter(topUsersAdapter); + holder.tv_gift_values.setText("等" + item.getTop_users().size() + "人"); + } + + + + } else { + holder.cl_gift_item.setBackgroundResource(com.xscm.moduleutil.R.mipmap.gift_wall_no_liang); + ImageLoader.loadImage(convertView.getContext(), holder.iv_gift_image, item.getBase_image(),0.4f); + holder.tv_gift_values.setVisibility(View.GONE); + holder.gift_num.setVisibility(View.GONE); + holder.rv_gift_user_list.setVisibility(View.GONE); + } + + + return convertView; + } + + static class ViewHolder { + TextView textView; + ImageView iv_gift_image; + + TextView tv_gift_values; + TextView gift_num; + TextView tv_price33; + RecyclerView rv_gift_user_list; + + ConstraintLayout cl_gift_item; + } +} \ No newline at end of file diff --git a/modulevocal/src/main/java/com/example/modulevocal/activity/ui/main/GiftWallConacts.java b/modulevocal/src/main/java/com/example/modulevocal/activity/ui/main/GiftWallConacts.java new file mode 100644 index 00000000..f2661525 --- /dev/null +++ b/modulevocal/src/main/java/com/example/modulevocal/activity/ui/main/GiftWallConacts.java @@ -0,0 +1,23 @@ +package com.example.modulevocal.activity.ui.main; + +import android.app.Activity; +import com.xscm.moduleutil.activity.IPresenter; +import com.xscm.moduleutil.activity.IView; +import com.xscm.moduleutil.bean.GiftUserWallBean; + +/** + * com.example.modulevocal.activity.ui.main + * qx + * 2025/11/5 + */ +public class GiftWallConacts { + public interface View extends IView { + void setGiftWall(GiftUserWallBean data); + } + + public interface IMePre extends IPresenter { + + void giftWall(String userId); + + } +} diff --git a/modulevocal/src/main/java/com/example/modulevocal/activity/ui/main/GiftWallPresenter.java b/modulevocal/src/main/java/com/example/modulevocal/activity/ui/main/GiftWallPresenter.java new file mode 100644 index 00000000..e50b1ab1 --- /dev/null +++ b/modulevocal/src/main/java/com/example/modulevocal/activity/ui/main/GiftWallPresenter.java @@ -0,0 +1,37 @@ +package com.example.modulevocal.activity.ui.main; + +import android.content.Context; +import com.xscm.moduleutil.bean.GiftUserWallBean; +import com.xscm.moduleutil.http.BaseObserver; +import com.xscm.moduleutil.presenter.BasePresenter; +import io.reactivex.disposables.Disposable; + +/** + * com.example.modulevocal.activity.ui.main + * qx + * 2025/11/5 + */ +public class GiftWallPresenter extends BasePresenter implements GiftWallConacts.IMePre{ + public GiftWallPresenter(GiftWallConacts.View view, Context context) { + super(view, context); + } + + @Override + public void giftWall(String userId) { + api.giftWall(userId, new BaseObserver() { + @Override + public void onSubscribe(Disposable d) { + addDisposable(d); + } + + @Override + public void onNext(GiftUserWallBean giftBeans) { + MvpRef.get().setGiftWall(giftBeans); + } + + @Override + public void onComplete() { + } + }); + } +} diff --git a/modulevocal/src/main/java/com/example/modulevocal/activity/ui/main/PageViewModel.java b/modulevocal/src/main/java/com/example/modulevocal/activity/ui/main/PageViewModel.java new file mode 100644 index 00000000..d8c3cefc --- /dev/null +++ b/modulevocal/src/main/java/com/example/modulevocal/activity/ui/main/PageViewModel.java @@ -0,0 +1,58 @@ +package com.example.modulevocal.activity.ui.main; + +import static androidx.lifecycle.Transformations.map; + +import androidx.arch.core.util.Function; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.ViewModel; +import com.xscm.moduleutil.bean.GiftUserWallBean; + +import java.util.List; + +public class PageViewModel extends ViewModel { + + private MutableLiveData mIndex = new MutableLiveData<>(); + private LiveData mText = map(mIndex, input -> "Hello world from section: " + input); + private MutableLiveData> mLiangDataList = new MutableLiveData<>(); + private MutableLiveData> mNoLiangDataList = new MutableLiveData<>(); + + // 根据索引返回不同的数据集合 + private LiveData> mDataList = map(mIndex, input -> { + if (input == 1) { + return mLiangDataList.getValue(); + } else if (input == 2) { + return mNoLiangDataList.getValue(); + } + return null; + }); + + public void setIndex(int index) { + mIndex.setValue(index); + } + + public LiveData getText() { + return mText; + } + + // 获取根据索引动态变化的数据集合 + public LiveData> getDataList() { + return mDataList; + } + + // 设置liang数据集合 + public void setLiangDataList(List dataList) { + for (GiftUserWallBean.GiftWallBean bean : dataList) { + bean.set_liang(true); + } + mLiangDataList.setValue(dataList); + } + + // 设置no_liang数据集合 + public void setNoLiangDataList(List dataList) { + for (GiftUserWallBean.GiftWallBean bean : dataList) { + bean.set_liang(false); + } + mNoLiangDataList.setValue(dataList); + } +} \ No newline at end of file diff --git a/modulevocal/src/main/java/com/example/modulevocal/activity/ui/main/PlaceholderFragment.java b/modulevocal/src/main/java/com/example/modulevocal/activity/ui/main/PlaceholderFragment.java new file mode 100644 index 00000000..30a8318b --- /dev/null +++ b/modulevocal/src/main/java/com/example/modulevocal/activity/ui/main/PlaceholderFragment.java @@ -0,0 +1,98 @@ +package com.example.modulevocal.activity.ui.main; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.GridView; +import android.widget.TextView; +import androidx.annotation.Nullable; +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.Observer; +import androidx.lifecycle.ViewModelProvider; +import com.example.modulevocal.databinding.FragmentGiftWallBinding; +import com.xscm.moduleutil.bean.GiftUserWallBean; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +/** + * A placeholder fragment containing a simple view. + */ +public class PlaceholderFragment extends Fragment { + + private static final String ARG_SECTION_NUMBER = "section_number"; + + private PageViewModel pageViewModel; + private FragmentGiftWallBinding binding; + + private GiftWallAdapter mGiftWallAdapter; + + public static PlaceholderFragment newInstance(int index) { + PlaceholderFragment fragment = new PlaceholderFragment(); +// Bundle bundle = new Bundle(); +// bundle.putInt(ARG_SECTION_NUMBER, index); +// fragment.setArguments(bundle); + return fragment; + } + + @Override + public void onAttach(@NonNull @NotNull Context context) { + super.onAttach(context); + pageViewModel = new ViewModelProvider(this).get(PageViewModel.class); + int index = 1; + if (getArguments() != null) { + index = getArguments().getInt(ARG_SECTION_NUMBER); + + // 获取传递的礼物列表数据 + List giftList = + (List) getArguments().getSerializable("gift_list"); + + // 将数据设置到 ViewModel + if (giftList != null) { + if (index == 1){ + pageViewModel.setLiangDataList(giftList); + }else if (index == 2){ + pageViewModel.setNoLiangDataList(giftList); + } + } + } + pageViewModel.setIndex(index); + + mGiftWallAdapter= new GiftWallAdapter(new ArrayList<>()); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + } + + @Override + public View onCreateView( + @NonNull LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + + binding = FragmentGiftWallBinding.inflate(inflater, container, false); + View root = binding.getRoot(); + // 设置 GridView + GridView gridView = binding.gridView; + gridView.setAdapter(mGiftWallAdapter); + // 观察数据变化并更新 GridView + pageViewModel.getDataList().observe(getViewLifecycleOwner(), dataList -> { + if (dataList != null) { + mGiftWallAdapter.updateData(dataList); + } + }); + return root; + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + binding = null; + } +} \ No newline at end of file diff --git a/modulevocal/src/main/java/com/example/modulevocal/activity/ui/main/SectionsPagerAdapter.java b/modulevocal/src/main/java/com/example/modulevocal/activity/ui/main/SectionsPagerAdapter.java new file mode 100644 index 00000000..013dc254 --- /dev/null +++ b/modulevocal/src/main/java/com/example/modulevocal/activity/ui/main/SectionsPagerAdapter.java @@ -0,0 +1,70 @@ +package com.example.modulevocal.activity.ui.main; + +import android.content.Context; +import android.os.Bundle; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.StringRes; +import androidx.fragment.app.*; +import androidx.viewpager2.adapter.FragmentStateAdapter; +import com.xscm.moduleutil.bean.GiftUserWallBean; + +import java.io.Serializable; + +/** + * A [FragmentPagerAdapter] that returns a fragment corresponding to + * one of the sections/tabs/pages. + */ +public class SectionsPagerAdapter extends FragmentStateAdapter { + + @StringRes + private static final int[] TAB_TITLES = new int[]{com.xscm.moduleutil.R.string.tab_text_1, com.xscm.moduleutil.R.string.tab_text_2}; + private final Context mContext; + private GiftUserWallBean giftData; // 添加数据字段 + +// public SectionsPagerAdapter(Context context, FragmentManager fm, GiftUserWallBean giftData) { +// super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); +// this.mContext = context; +// this.giftData = giftData; +// } + + public SectionsPagerAdapter(@NonNull FragmentActivity fragmentActivity, GiftUserWallBean giftData) { + super(fragmentActivity); + this.mContext = fragmentActivity; + this.giftData = giftData; + } + + @NonNull + @Override + public Fragment createFragment(int position) { + // 创建 Fragment 实例并传递参数 + PlaceholderFragment fragment = PlaceholderFragment.newInstance(position + 1); + Bundle args = new Bundle(); + + // 根据位置传递不同的数据 + if (giftData != null) { + if (position == 0) { + // 传递 liang 数据 + args.putSerializable("gift_list", (Serializable) giftData.getLiang()); + } else if (position == 1) { + // 传递 no_liang 数据 + args.putSerializable("gift_list", (Serializable) giftData.getNo_liang()); + } + } + args.putInt("section_number", position+1); + fragment.setArguments(args); + return fragment; + } + @Override + public int getItemCount() { + return 2; // 假设 GiftUserWallBean 包含 list 数据结构 + } + + public CharSequence getPageTitle(int position) { + return mContext.getResources().getString(TAB_TITLES[position]); + } + + + + +} \ No newline at end of file diff --git a/modulevocal/src/main/java/com/example/modulevocal/adapter/BlackAdapter.java b/modulevocal/src/main/java/com/example/modulevocal/adapter/BlackAdapter.java index a7d7a0f3..2aed57b4 100644 --- a/modulevocal/src/main/java/com/example/modulevocal/adapter/BlackAdapter.java +++ b/modulevocal/src/main/java/com/example/modulevocal/adapter/BlackAdapter.java @@ -45,7 +45,7 @@ public class BlackAdapter extends BaseQuickAdapter mDataList; + + public GridNobleAdapter(List dataList) { + this.mDataList = dataList; + } + + public GridNobleAdapter() { + + } + + public void updateData(List newDataList) { + this.mDataList = newDataList; + notifyDataSetChanged(); + } + + @Override + public int getCount() { + return mDataList != null ? mDataList.size() : 0; + } + + @Override + public Object getItem(int position) { + return mDataList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + // 实现 GridView item 的布局和数据绑定 + // 这里返回每个 GridView 项的视图 + ViewHolder holder; + if (convertView == null) { + convertView = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_noble_tq, parent, false); + holder = new ViewHolder(); + holder.tv_hz_mc = convertView.findViewById(R.id.tv_hz_mc); + holder.ci_image = convertView.findViewById(R.id.ci_image); + holder.tv_hz_detail = convertView.findViewById(R.id.tv_hz_detail); + convertView.setTag(holder); + } else { + holder = (ViewHolder) convertView.getTag(); + } + + NobilitList.Power.PowerItem item = mDataList.get(position); + holder.tv_hz_detail.setText(item.getContent()); + holder.tv_hz_mc.setText(item.getName()); + ImageUtils.loadHeadCC(item.getImage(), holder.ci_image); + + + + + return convertView; + } + + static class ViewHolder { + TextView tv_hz_mc; + CircularImage ci_image; + + TextView tv_hz_detail; + } +} diff --git a/modulevocal/src/main/java/com/example/modulevocal/adapter/NoblePrivilegeAdapter.java b/modulevocal/src/main/java/com/example/modulevocal/adapter/NoblePrivilegeAdapter.java new file mode 100644 index 00000000..d235dcf9 --- /dev/null +++ b/modulevocal/src/main/java/com/example/modulevocal/adapter/NoblePrivilegeAdapter.java @@ -0,0 +1,24 @@ +package com.example.modulevocal.adapter; + +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.BaseViewHolder; +import com.example.modulevocal.R; +import com.xscm.moduleutil.bean.NobilityPrice; + +/** + * com.example.modulevocal.adapter + * qx + * 2025/11/10 + */ +// NoblePrivilegeAdapter.java +public class NoblePrivilegeAdapter extends BaseQuickAdapter { + + public NoblePrivilegeAdapter() { + super(R.layout.item_noble_privilege); + } + + @Override + protected void convert(BaseViewHolder helper, NobilityPrice.PowerItem item) { + helper.setText(R.id.tv_title, item.getContent()); + } +} diff --git a/modulevocal/src/main/java/com/example/modulevocal/adapter/NobliityBannerAdapter.java b/modulevocal/src/main/java/com/example/modulevocal/adapter/NobliityBannerAdapter.java new file mode 100644 index 00000000..97a43c62 --- /dev/null +++ b/modulevocal/src/main/java/com/example/modulevocal/adapter/NobliityBannerAdapter.java @@ -0,0 +1,54 @@ +package com.example.modulevocal.adapter; + +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; +import com.example.modulevocal.R; +import com.xscm.moduleutil.bean.NobilitList; +import com.xscm.moduleutil.bean.TopRoom; +import com.xscm.moduleutil.utils.ImageLoader; +import com.xscm.moduleutil.utils.ImageUtils; +import com.zhpan.bannerview.BaseBannerAdapter; +import com.zhpan.bannerview.BaseViewHolder; + +/** + *com.example.modulevocal.adapter + *qx + *2025/11/10 + * + */ +public class NobliityBannerAdapter extends BaseBannerAdapter { + + private OnItemClickListener onItemClickListener; + + private int mCurrentPosition; + + public int getmCurrentPosition() { + return mCurrentPosition; + } + + public void setmCurrentPosition(int mCurrentPosition) { + this.mCurrentPosition = mCurrentPosition; + } + + public void setOnItemClickListener(OnItemClickListener listener) { + this.onItemClickListener = listener; + } + @Override + protected void bindData(BaseViewHolder holder, NobilitList data, int position, int pageSize) { + if (position>=mCurrentPosition) { + ImageUtils.loadHeadCC(data.getImage(), holder.itemView.findViewById(R.id.iv_follow_bg)); +// ImageLoader.loadImage(holder.itemView.getContext(),holder.itemView.findViewById(R.id.iv_follow_bg),data.getImage(),1f); + }else { + ImageLoader.loadImage(holder.itemView.getContext(),holder.itemView.findViewById(R.id.iv_follow_bg),data.getImage(),0f); + } + } + + public interface OnItemClickListener { + void onItemClick(View view, TopRoom data, int position); + } + @Override + public int getLayoutId(int viewType) { + return R.layout.index_item_nobli; + } +} \ No newline at end of file diff --git a/modulevocal/src/main/java/com/example/modulevocal/adapter/UserGiftWallAdapter.java b/modulevocal/src/main/java/com/example/modulevocal/adapter/UserGiftWallAdapter.java index a8333d2f..55f31831 100644 --- a/modulevocal/src/main/java/com/example/modulevocal/adapter/UserGiftWallAdapter.java +++ b/modulevocal/src/main/java/com/example/modulevocal/adapter/UserGiftWallAdapter.java @@ -29,7 +29,7 @@ public class UserGiftWallAdapter extends BaseQuickAdapter bannerModels); } public interface IMePre extends IPresenter { @@ -33,6 +37,8 @@ public final class MeConacts { void entranceCheckFirstRecharge(); void getMemberList(String userId, int page); + + void wallet(); } } diff --git a/modulevocal/src/main/java/com/example/modulevocal/conacts/NobleTitleConacts.java b/modulevocal/src/main/java/com/example/modulevocal/conacts/NobleTitleConacts.java new file mode 100644 index 00000000..a2f3d776 --- /dev/null +++ b/modulevocal/src/main/java/com/example/modulevocal/conacts/NobleTitleConacts.java @@ -0,0 +1,40 @@ +package com.example.modulevocal.conacts; + +import android.app.Activity; +import com.xscm.moduleutil.activity.IPresenter; +import com.xscm.moduleutil.activity.IView; +import com.xscm.moduleutil.bean.*; + +import java.util.List; + +/** + * com.example.modulevocal.conacts + * qx + * 2025/11/8 + */ +public class NobleTitleConacts { + + public interface View extends IView { + void getNobilityDetail(NobilitDeatils nobilitDeatils); + + void getNobilityList(List nobilitLists); + + void bindType(BindType bindType); + + void appPay(AppPay appPay); + + void getNobilityPrice(NobilityPrice nobilityPrice); + } + + public interface IMePre extends IPresenter { + void getNobilityDetail(); + + void getNobilityList(); + + void bindType(String userId); + + void appPay(String user_id, String money, String type, String type_id); + + void getNobilityPrice(String id); + } +} diff --git a/modulevocal/src/main/java/com/example/modulevocal/conacts/SettingConacts.java b/modulevocal/src/main/java/com/example/modulevocal/conacts/SettingConacts.java index aedc0996..8c5ad23b 100644 --- a/modulevocal/src/main/java/com/example/modulevocal/conacts/SettingConacts.java +++ b/modulevocal/src/main/java/com/example/modulevocal/conacts/SettingConacts.java @@ -15,5 +15,7 @@ public class SettingConacts { void clearLoginInfo(); void cancel(); + + void getModifyHideStatus(String hide_status); } } diff --git a/modulevocal/src/main/java/com/example/modulevocal/fragment/UserHomepageFragment.java b/modulevocal/src/main/java/com/example/modulevocal/fragment/UserHomepageFragment.java index 8a3e3d48..cb833fc0 100644 --- a/modulevocal/src/main/java/com/example/modulevocal/fragment/UserHomepageFragment.java +++ b/modulevocal/src/main/java/com/example/modulevocal/fragment/UserHomepageFragment.java @@ -116,11 +116,21 @@ public class UserHomepageFragment extends BaseMvpFragment bannerModels) { + mBinding.banner.setBannerData(com.xscm.moduleutil.R.layout.index_image_banner, bannerModels); + } + /** * 首充有礼显示 */ diff --git a/modulevocal/src/main/java/com/example/modulevocal/fragment/zhuangb/ZhuangBanShangChengFragment.java b/modulevocal/src/main/java/com/example/modulevocal/fragment/zhuangb/ZhuangBanShangChengFragment.java index dda7f7d6..4d0de711 100644 --- a/modulevocal/src/main/java/com/example/modulevocal/fragment/zhuangb/ZhuangBanShangChengFragment.java +++ b/modulevocal/src/main/java/com/example/modulevocal/fragment/zhuangb/ZhuangBanShangChengFragment.java @@ -1,7 +1,6 @@ package com.example.modulevocal.fragment.zhuangb; import static android.view.View.GONE; -import static com.xscm.moduleutil.utils.ImageLoader.loadImage; import android.os.Bundle; import android.view.View; diff --git a/modulevocal/src/main/java/com/example/modulevocal/presenter/EditUserPresenter.java b/modulevocal/src/main/java/com/example/modulevocal/presenter/EditUserPresenter.java index f204b041..26bfdf4d 100644 --- a/modulevocal/src/main/java/com/example/modulevocal/presenter/EditUserPresenter.java +++ b/modulevocal/src/main/java/com/example/modulevocal/presenter/EditUserPresenter.java @@ -12,13 +12,16 @@ import com.xscm.moduleutil.utils.cos.CosUploadManager; import com.xscm.moduleutil.utils.oss.OSSOperUtils; import java.io.File; +import java.lang.ref.WeakReference; import java.util.List; import io.reactivex.disposables.Disposable; public class EditUserPresenter extends BasePresenter implements EditUserConactos.IMePre { + EditUserConactos.View mView; public EditUserPresenter(EditUserConactos.View view, Context context) { super(view, context); + mView = view; } @Override @@ -85,6 +88,9 @@ public class EditUserPresenter extends BasePresenter impl @Override public void onNext(UserInfo userInfo) { + if (MvpRef==null){ + MvpRef=new WeakReference<>(mView); + } MvpRef.get().getUserHomeSuccess(userInfo); } }); diff --git a/modulevocal/src/main/java/com/example/modulevocal/presenter/MePresenter.java b/modulevocal/src/main/java/com/example/modulevocal/presenter/MePresenter.java index f5a5a95f..90afa0c7 100644 --- a/modulevocal/src/main/java/com/example/modulevocal/presenter/MePresenter.java +++ b/modulevocal/src/main/java/com/example/modulevocal/presenter/MePresenter.java @@ -3,16 +3,22 @@ package com.example.modulevocal.presenter; import android.content.Context; import com.example.modulevocal.conacts.MeConacts; +import com.xscm.moduleutil.bean.BannerModel; import com.xscm.moduleutil.bean.UserInfo; +import com.xscm.moduleutil.bean.WalletBean; import com.xscm.moduleutil.http.BaseObserver; import com.xscm.moduleutil.presenter.BasePresenter; import io.reactivex.disposables.Disposable; -public class MePresenter extends BasePresenter implements MeConacts.IMePre { +import java.lang.ref.WeakReference; +import java.util.List; +public class MePresenter extends BasePresenter implements MeConacts.IMePre { + MeConacts.View mView; public MePresenter(MeConacts.View view, Context context) { super(view, context); + mView = view; } @Override @@ -164,28 +170,39 @@ public class MePresenter extends BasePresenter implements MeCona } - public void getConfig() { -// api.appUpdate(new com.qpyy.libcommon.http.BaseObserver() { -// @Override -// public void onSubscribe(Disposable d) { -// addDisposable(d); -// } -// -// @Override -// public void onNext(AppUpdateModel appUpdateModel) { -// String channelId = "default"; -// try { -// channelId = MetaDataUtils.getMetaDataInApp("TD_CHANNEL_ID"); -// } catch (Exception e) { -// e.printStackTrace(); -// } -// MvpRef.get().hideSkill(appUpdateModel != null && appUpdateModel.getChannels() != null && appUpdateModel.getChannels().contains(channelId)); -// } -// -// @Override -// public void onComplete() { -// -// } -// }); + @Override + public void wallet() { + api.wallet(new BaseObserver() { + @Override + public void onSubscribe(Disposable d) { + addDisposable(d); + } + + @Override + public void onNext(WalletBean walletBean) { + MvpRef.get().wallet(walletBean); + } + }); + } + + public void getBanners(String s) { +// Type listType = new TypeToken>() {}.getType(); +// List restoredRoomModels = GsonUtils.getGSON().fromJson(SpUtils.getHomeBanner(), listType); +// MvpRef.get().setBanners(restoredRoomModels); + api.getBanners(s,new BaseObserver>() { + @Override + public void onSubscribe(Disposable d) { + addDisposable(d); + } + + @Override + public void onNext(List bannerModels) { + if (MvpRef==null){ + MvpRef=new WeakReference<>(mView); + } + MvpRef.get().setBanners(bannerModels); + } + + }); } } diff --git a/modulevocal/src/main/java/com/example/modulevocal/presenter/NobleTitlePresenter.java b/modulevocal/src/main/java/com/example/modulevocal/presenter/NobleTitlePresenter.java new file mode 100644 index 00000000..19e3313a --- /dev/null +++ b/modulevocal/src/main/java/com/example/modulevocal/presenter/NobleTitlePresenter.java @@ -0,0 +1,118 @@ +package com.example.modulevocal.presenter; + +import android.content.Context; +import com.example.modulevocal.conacts.MeConacts; +import com.example.modulevocal.conacts.NobleTitleConacts; +import com.xscm.moduleutil.bean.*; +import com.xscm.moduleutil.http.BaseObserver; +import com.xscm.moduleutil.presenter.BasePresenter; +import io.reactivex.disposables.Disposable; +import org.jetbrains.annotations.NotNull; + +import java.lang.ref.WeakReference; +import java.util.List; + +/** + * com.example.modulevocal.presenter + * qx + * 2025/11/8 + */ +public class NobleTitlePresenter extends BasePresenter implements NobleTitleConacts.IMePre{ + private NobleTitleConacts.View mView; + public NobleTitlePresenter(NobleTitleConacts.View view, Context context) { + super(view, context); + mView = view; + } + + @Override + public void getNobilityDetail() { + api.getNobilityDetail(new BaseObserver() { + @Override + public void onSubscribe(@NotNull Disposable d) { + + } + + @Override + public void onNext(@NotNull NobilitDeatils nobilitDeatils) { + if (MvpRef==null){ + MvpRef=new WeakReference<>(mView); + } + MvpRef.get().getNobilityDetail(nobilitDeatils); + } + }); + } + + @Override + public void getNobilityList() { + api.getNobilityList(new BaseObserver>(){ + + @Override + public void onSubscribe(@NotNull Disposable d) { + addDisposable(d); + } + + @Override + public void onNext(@NotNull List nobilitLists) { + if (MvpRef==null){ + MvpRef=new WeakReference<>(mView); + } + MvpRef.get().getNobilityList(nobilitLists); + } + }); + } + @Override + public void bindType(String userId) { + api.bindType(userId, new BaseObserver() { + @Override + public void onSubscribe(Disposable d) { + addDisposable(d); + } + + @Override + public void onNext(BindType bindType) { + if (MvpRef==null){ + MvpRef=new WeakReference<>(mView); + } + MvpRef.get().bindType(bindType); + } + }); + } + + @Override + public void appPay(String user_id, String money, String type, String nobility_id) { + api.appPay(user_id, money, "", type,"","",nobility_id, new BaseObserver() { + @Override + public void onSubscribe(Disposable d) { + addDisposable(d); + } + + @Override + public void onNext(AppPay appPay) { + if (MvpRef==null){ + MvpRef=new WeakReference<>(mView); + } + MvpRef.get().appPay(appPay); + } + + }); + } + + @Override + public void getNobilityPrice(String id) { + api.getNobilityPrice(id, new BaseObserver() { + @Override + public void onSubscribe(@NotNull Disposable d) { + addDisposable(d); + } + + @Override + public void onNext(@NotNull NobilityPrice nobilityPrice) { + if (MvpRef==null){ + MvpRef=new WeakReference<>(mView); + } + MvpRef.get().getNobilityPrice(nobilityPrice); + } + }); + } + +} diff --git a/modulevocal/src/main/java/com/example/modulevocal/presenter/RechargePresenter.java b/modulevocal/src/main/java/com/example/modulevocal/presenter/RechargePresenter.java index 5cd2978a..fd751dda 100644 --- a/modulevocal/src/main/java/com/example/modulevocal/presenter/RechargePresenter.java +++ b/modulevocal/src/main/java/com/example/modulevocal/presenter/RechargePresenter.java @@ -51,7 +51,7 @@ public class RechargePresenter extends BasePresenter impl @Override public void appPay(String user_id, String money, String coin, String type, String type_params, String type_id) { - api.appPay(user_id, money, coin, type,type_params,type_id, new BaseObserver() { + api.appPay(user_id, money, coin, type,type_params,type_id,"", new BaseObserver() { @Override public void onSubscribe(Disposable d) { addDisposable(d); diff --git a/modulevocal/src/main/java/com/example/modulevocal/presenter/SettingPresenter.java b/modulevocal/src/main/java/com/example/modulevocal/presenter/SettingPresenter.java index d7cd5c7e..3767f481 100644 --- a/modulevocal/src/main/java/com/example/modulevocal/presenter/SettingPresenter.java +++ b/modulevocal/src/main/java/com/example/modulevocal/presenter/SettingPresenter.java @@ -13,8 +13,10 @@ import org.jetbrains.annotations.NotNull; import java.lang.ref.WeakReference; public class SettingPresenter extends BasePresenter implements SettingConacts.IMePre { + private SettingConacts.View mView; public SettingPresenter(SettingConacts.View view, Context context) { super(view, context); + mView = view; } @Override @@ -27,6 +29,9 @@ public class SettingPresenter extends BasePresenter impleme @Override public void onNext(String s) { + if (MvpRef==null){ + MvpRef=new WeakReference<>(mView); + } MvpRef.get().clearLoginInfo(s); } }); @@ -43,9 +48,27 @@ public class SettingPresenter extends BasePresenter impleme @Override public void onNext(String s) { + if (MvpRef==null){ + MvpRef=new WeakReference<>(mView); + } MvpRef.get().cancel(s); } }); } + @Override + public void getModifyHideStatus(String hide_status) { + api.getModifyHideStatus(hide_status, new BaseObserver() { + @Override + public void onSubscribe(@NotNull Disposable d) { + addDisposable(d); + } + + @Override + public void onNext(@NotNull String s) { + + } + }); + } + } diff --git a/modulevocal/src/main/res/drawable/noble_card_border.xml b/modulevocal/src/main/res/drawable/noble_card_border.xml new file mode 100644 index 00000000..2a3dd5e3 --- /dev/null +++ b/modulevocal/src/main/res/drawable/noble_card_border.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/modulevocal/src/main/res/layout/activity_change_password.xml b/modulevocal/src/main/res/layout/activity_change_password.xml index 35468d29..271ca756 100644 --- a/modulevocal/src/main/res/layout/activity_change_password.xml +++ b/modulevocal/src/main/res/layout/activity_change_password.xml @@ -2,7 +2,7 @@ + > diff --git a/modulevocal/src/main/res/layout/activity_gift_wall.xml b/modulevocal/src/main/res/layout/activity_gift_wall.xml new file mode 100644 index 00000000..b61709ad --- /dev/null +++ b/modulevocal/src/main/res/layout/activity_gift_wall.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/modulevocal/src/main/res/layout/activity_noble_details.xml b/modulevocal/src/main/res/layout/activity_noble_details.xml new file mode 100644 index 00000000..a940222f --- /dev/null +++ b/modulevocal/src/main/res/layout/activity_noble_details.xml @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/modulevocal/src/main/res/layout/activity_noble_payment.xml b/modulevocal/src/main/res/layout/activity_noble_payment.xml new file mode 100644 index 00000000..1632067b --- /dev/null +++ b/modulevocal/src/main/res/layout/activity_noble_payment.xml @@ -0,0 +1,392 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/modulevocal/src/main/res/layout/activity_noble_title.xml b/modulevocal/src/main/res/layout/activity_noble_title.xml new file mode 100644 index 00000000..acd5f0f2 --- /dev/null +++ b/modulevocal/src/main/res/layout/activity_noble_title.xml @@ -0,0 +1,286 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/modulevocal/src/main/res/layout/activity_setting.xml b/modulevocal/src/main/res/layout/activity_setting.xml index 8c37f8f7..e1feefe0 100644 --- a/modulevocal/src/main/res/layout/activity_setting.xml +++ b/modulevocal/src/main/res/layout/activity_setting.xml @@ -112,6 +112,35 @@ android:layout_alignParentBottom="true" android:background="@color/color_FFE5E5E5" /> + + + + + + + + + + + - - - - - - - - - + + + + + \ No newline at end of file diff --git a/modulevocal/src/main/res/layout/fragment_vocal_range.xml b/modulevocal/src/main/res/layout/fragment_vocal_range.xml index 37f08467..32f5af19 100644 --- a/modulevocal/src/main/res/layout/fragment_vocal_range.xml +++ b/modulevocal/src/main/res/layout/fragment_vocal_range.xml @@ -1,586 +1,1033 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools"> - - + android:overScrollMode="never" + android:background="@mipmap/home_bj" + android:paddingBottom="@dimen/dp_60"> + + + android:layout_width="match_parent" + android:layout_height="wrap_content"> + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/dp_48" + android:layout_marginEnd="@dimen/dp_16" + android:gravity="center_vertical" + android:orientation="horizontal" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" + android:visibility="gone"> + + android:layout_width="@dimen/dp_24" + android:layout_height="@dimen/dp_24" + android:layout_marginRight="@dimen/dp_11" + android:src="@drawable/image_yq"/> + + android:layout_width="@dimen/dp_24" + android:layout_height="@dimen/dp_24" + android:layout_marginRight="@dimen/dp_11" + android:src="@drawable/custom"/> + android:layout_width="@dimen/dp_24" + android:layout_height="@dimen/dp_24" + android:layout_marginRight="@dimen/dp_11" + android:src="@mipmap/setting"/> - - - - - - + + - + + + android:textColor="#fff" + android:textSize="@dimen/sp_16" + android:layout_marginTop="@dimen/dp_5" + app:layout_constraintStart_toEndOf="@+id/riv_user_head" + app:layout_constraintTop_toTopOf="@+id/riv_user_head" + android:layout_marginStart="@dimen/dp_14" + tools:text="用户22333333"/> - + android:textColor="@color/color_FFFFFFE0" + android:textSize="@dimen/sp_12" + app:layout_constraintStart_toStartOf="@+id/tv_nick_name" + app:layout_constraintTop_toBottomOf="@+id/tv_nick_name" + tools:text="22222"/> - + - - - + + + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintTop_toBottomOf="@+id/beautiful_view" + app:layout_constraintStart_toStartOf="@+id/beautiful_view" + /> - - - - - + + + + + + + + - - - - - - + + + + + + + - - - - - + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + android:id="@+id/tv_home" + android:layout_width="@dimen/dp_60" + android:layout_height="@dimen/dp_33" + android:src="@mipmap/me_edit" + android:layout_marginEnd="@dimen/dp_16" + android:scaleType="fitCenter" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintEnd_toEndOf="parent" + /> - - - - - - - - - - - - - - - - - - - - - - - - + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/me_linearlayout2"> + + + android:id="@+id/tv_follow" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:singleLine="true" + android:text="0" + android:fontFamily="@font/semibold" + android:textColor="#CCCDC8" + android:textSize="@dimen/sp_22"/> + android:layout_width="wrap_content" + android:layout_height="@dimen/dp_17" + android:layout_marginTop="@dimen/dp_1" + android:text="关注" + android:textColor="#CCCDC8" + android:textSize="@dimen/sp_12"/> + android:layout_width="@dimen/dp_1" + android:layout_height="@dimen/dp_18" + android:layout_gravity="center_vertical" + android:background="#444541" + /> + android:id="@+id/ll_fans" + android:layout_width="@dimen/dp_0" + android:layout_height="wrap_content" + android:layout_weight="1" + android:gravity="center" + android:orientation="vertical"> + android:id="@+id/tv_fans" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:singleLine="true" + android:fontFamily="@font/semibold" + android:text="0" + android:textColor="#CCCDC8" + android:textSize="@dimen/sp_22"/> + + + + + + + + android:layout_weight="1" + android:gravity="center" + android:orientation="vertical" + android:visibility="visible"> + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + android:layout_marginEnd="@dimen/dp_16" + app:cardBackgroundColor="#231F2C" + app:cardCornerRadius="@dimen/dp_8"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/dp_8" + android:orientation="horizontal"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + android:layout_marginStart="@dimen/dp_16" + android:layout_marginEnd="@dimen/dp_16" + android:layout_marginTop="@dimen/dp_12" + app:cardBackgroundColor="#231F2C" + app:cardCornerRadius="@dimen/dp_8"> - - + android:orientation="vertical" + android:paddingStart="@dimen/dp_16" + android:paddingBottom="@dimen/dp_12" + android:paddingEnd="@dimen/dp_16"> - - + android:text="更多" + android:textColor="#929196" + android:layout_marginTop="@dimen/dp_12" + android:textSize="@dimen/sp_14"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:layout_marginTop="@dimen/dp_12" + android:orientation="horizontal"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modulevocal/src/main/res/layout/index_item_nobli.xml b/modulevocal/src/main/res/layout/index_item_nobli.xml new file mode 100644 index 00000000..de08c950 --- /dev/null +++ b/modulevocal/src/main/res/layout/index_item_nobli.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/modulevocal/src/main/res/layout/item_gift_wall.xml b/modulevocal/src/main/res/layout/item_gift_wall.xml new file mode 100644 index 00000000..c57d98d9 --- /dev/null +++ b/modulevocal/src/main/res/layout/item_gift_wall.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/modulevocal/src/main/res/layout/item_noble_privilege.xml b/modulevocal/src/main/res/layout/item_noble_privilege.xml new file mode 100644 index 00000000..6236ad8f --- /dev/null +++ b/modulevocal/src/main/res/layout/item_noble_privilege.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/modulevocal/src/main/res/layout/item_noble_tq.xml b/modulevocal/src/main/res/layout/item_noble_tq.xml new file mode 100644 index 00000000..45a851d4 --- /dev/null +++ b/modulevocal/src/main/res/layout/item_noble_tq.xml @@ -0,0 +1,46 @@ + + + + + + + + + + \ No newline at end of file diff --git a/modulevocal/src/main/res/layout/user_top.xml b/modulevocal/src/main/res/layout/user_top.xml index be7eba06..3a4d62a2 100644 --- a/modulevocal/src/main/res/layout/user_top.xml +++ b/modulevocal/src/main/res/layout/user_top.xml @@ -71,7 +71,8 @@ android:layout_height="@dimen/dp_20" android:text="ID:" android:textColor="@color/color_FF999999" - android:textSize="@dimen/sp_12" /> + android:textSize="@dimen/sp_12" + android:visibility="gone"/> + + + 48dp + \ No newline at end of file diff --git a/modulevocal/src/main/res/values-w1240dp/dimens.xml b/modulevocal/src/main/res/values-w1240dp/dimens.xml new file mode 100644 index 00000000..d73f4a35 --- /dev/null +++ b/modulevocal/src/main/res/values-w1240dp/dimens.xml @@ -0,0 +1,3 @@ + + 200dp + \ No newline at end of file diff --git a/modulevocal/src/main/res/values-w600dp/dimens.xml b/modulevocal/src/main/res/values-w600dp/dimens.xml new file mode 100644 index 00000000..22d7f004 --- /dev/null +++ b/modulevocal/src/main/res/values-w600dp/dimens.xml @@ -0,0 +1,3 @@ + + 48dp + \ No newline at end of file diff --git a/modulevocal/src/main/res/values-w820dp/dimens.xml b/modulevocal/src/main/res/values-w820dp/dimens.xml new file mode 100644 index 00000000..9309de98 --- /dev/null +++ b/modulevocal/src/main/res/values-w820dp/dimens.xml @@ -0,0 +1,6 @@ + + + 64dp + \ No newline at end of file diff --git a/modulevocal/src/main/res/values/dimens.xml b/modulevocal/src/main/res/values/dimens.xml new file mode 100644 index 00000000..0a87b6e7 --- /dev/null +++ b/modulevocal/src/main/res/values/dimens.xml @@ -0,0 +1,8 @@ + + + 16dp + 16dp + 16dp + 16dp + 8dp + \ No newline at end of file diff --git a/modulevocal/src/main/res/values/strings.xml b/modulevocal/src/main/res/values/strings.xml index 6048840e..e5f8fdc2 100644 --- a/modulevocal/src/main/res/values/strings.xml +++ b/modulevocal/src/main/res/values/strings.xml @@ -1,4 +1,2 @@ - - Hello blank fragment \ No newline at end of file diff --git a/modulevoice/src/main/java/com/example/modulevoice/adapter/SearchUserResultAdapter.java b/modulevoice/src/main/java/com/example/modulevoice/adapter/SearchUserResultAdapter.java index 38ce7892..c434a4e8 100644 --- a/modulevoice/src/main/java/com/example/modulevoice/adapter/SearchUserResultAdapter.java +++ b/modulevoice/src/main/java/com/example/modulevoice/adapter/SearchUserResultAdapter.java @@ -46,7 +46,7 @@ public class SearchUserResultAdapter extends BaseQuickAdapter>() {}.getType(); // List restoredRoomModels = GsonUtils.getGSON().fromJson(SpUtils.getHomeBanner(), listType); // MvpRef.get().setBanners(restoredRoomModels); - api.getBanners(new BaseObserver>() { + api.getBanners(s,new BaseObserver>() { @Override public void onSubscribe(Disposable d) { addDisposable(d); @@ -74,8 +74,6 @@ public class VoiceCategoryPresenter extends BasePresenter