最近阶段工作相关总结,微信支付/应用商店/FileDownLoader/编码转换/流式布局
1.Android微信支付回调区分
总的来说就是在request中使用 request.extData 字段进行自己业务的区分,比如 充值/支付/分享等
private void wxPay(WeiPayModel.ResultData data,String payOrRecharge) { IWXAPI api = WXAPIFactory.createWXAPI(mContext,Constant.APP_ID_WX); api.registerApp(Constant.APP_ID_WX); Log.d("MyInfo","data="+data.toString()); PayReq request = new PayReq(); request.appId = Constant.APP_ID_WX; request.partnerId = data.getPartnerId(); request.prepayId= data.getPrepayId(); request.packageValue = "Sign=WXPay"; request.nonceStr= data.getNonceStr(); request.timeStamp= data.getTimeStamp(); request.sign= data.getSign(); request.extData=payOrRecharge; api.sendReq(request); }
然后在回调WXPayEntryActivity 中:
@Override public void onResp(BaseResp baseResp) { Log.d("MyInfo", "onPayFinish, errCode = " + baseResp.errCode+"errMsg="+baseResp.errStr); if (baseResp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) { int errCord = baseResp.errCode; if (errCord == 0) { PayResp resps = (PayResp) baseResp; String payType = resps.extData; switch (payType) { case Constant.WEIPAY_RECHARGE: //充值成功 break; case Constant.WEIPAY_PAY: //支付成功 break; } }else{ if(errCord==-2){ ToastUtil.show(mContext,"用户取消!"); } else { ToastUtil.show(mContext,"支付失败!"); } } finish(); } }
2.Android跳转到应用商店详情页面(更全面)
3.Android 利用FileDownloader进行多线程下载
//喜马拉雅app下载地址String url="http://s1.xmcdn.com/apk/MainApp_v6.6.93.3_c298_release_proguard_200803_and-a1.apk"; ViewHolder holder=new ViewHolder(dialog,1); String path=Environment.getExternalStorageDirectory()+"/customName.apk"; FileDownloader.getImpl().create(url) .setPath(path) .setCallbackProgressTimes(300) .setMinIntervalUpdateSpeed(400) .setTag(holder) .setListener(new FileDownloadSampleListener() { @Override protected void pending(BaseDownloadTask task, int soFarBytes, int totalBytes) { super.pending(task, soFarBytes, totalBytes); ((ViewHolder) task.getTag()).updatePending(task); } @Override protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) { super.progress(task, soFarBytes, totalBytes); ((ViewHolder) task.getTag()).updateProgress(soFarBytes, totalBytes, task.getSpeed()); } @Override protected void error(BaseDownloadTask task, Throwable e) { super.error(task, e); ((ViewHolder) task.getTag()).updateError(e, task.getSpeed()); } @Override protected void connected(BaseDownloadTask task, String etag, boolean isContinue, int soFarBytes, int totalBytes) { super.connected(task, etag, isContinue, soFarBytes, totalBytes); ((ViewHolder) task.getTag()).updateConnected(etag, task.getFilename()); } @Override protected void paused(BaseDownloadTask task, int soFarBytes, int totalBytes) { super.paused(task, soFarBytes, totalBytes); ((ViewHolder) task.getTag()).updatePaused(task.getSpeed()); } @Override protected void completed(BaseDownloadTask task) { super.completed(task); ((ViewHolder) task.getTag()).updateCompleted(task); } @Override protected void warn(BaseDownloadTask task) { super.warn(task); ((ViewHolder) task.getTag()).updateWarn(); } }) .start();
ViewHolder 类:
private class ViewHolder { private ProgressDialog progressBar1; private int viewHolderPosition; public ViewHolder(final ProgressDialog progressBar1, final int position) { this.progressBar1 = progressBar1; this.viewHolderPosition = position; } private void updateSpeed(int speed) { Log.d("MyInfo","updateSpeed"+String.format("下载速度: %dKB/s", speed)); } public void updateProgress(final int sofar, final int total, final int speed) { if (total == -1) { // chunked transfer encoding data progressBar1.setIndeterminate(true); } else { progressBar1.setMax(total/1024/1024); progressBar1.setProgress(sofar/1024/1024); } updateSpeed(speed); } public void updatePending(BaseDownloadTask task) { Log.d("MyInfo","updatePending 下载名称 :"+task.getFilename()); } public void updatePaused(final int speed) { Log.d("MyInfo","updatePaused "+String.format("updatePaused 已停止下载 ", viewHolderPosition)); updateSpeed(speed); progressBar1.setIndeterminate(false); } public void updateConnected(String etag, String filename) { Log.d("MyInfo","updateConnected 名称 :"+filename+",etag:"+etag); } public void updateWarn() { Log.d("MyInfo","updateWarn "+String.format("warn %d", viewHolderPosition)); progressBar1.setIndeterminate(false); } public void updateError(final Throwable ex, final int speed) { Log.d("MyInfo","updateError "+String.format("error %d %s", viewHolderPosition, ex)); updateSpeed(speed); progressBar1.setIndeterminate(false); progressBar1.dismiss(); ex.printStackTrace(); //发送消息 Message message=updateHandler.obtainMessage(); message.what=1; message.obj="update"; updateHandler.sendMessage(message); } public void updateCompleted(final BaseDownloadTask task) { Log.d("MyInfo","updateCompleted:"+String.format("下载完成,下载路径 %d %s", viewHolderPosition, task.getTargetFilePath())); updateSpeed(task.getSpeed());// progressBar1.setIndeterminate(false); progressBar1.setMax(task.getSmallFileTotalBytes()/1024/1024); progressBar1.setProgress(task.getSmallFileSoFarBytes()/1024/1024); progressBar1.dismiss(); //下载完成, } }
4.在线编码转换
5.自定义流式布局,修改FlowLayout源码,让其支持设置最大行数
ps: 5本人接到产品需求,只显示一行,最后多余的部分 显示 … 省略号
类如下:
做了稍微的改动:(不喜勿喷,欢迎指正)
package com.wy.simula.widget.view;import android.content.Context;import android.graphics.Canvas;import android.util.AttributeSet;import android.view.View;import android.view.ViewGroup;import android.widget.FrameLayout;import android.widget.TextView;import com.wy.simula.R;import com.wy.simula.util.DisplayUtils;import java.util.ArrayList;import java.util.Collections;import java.util.List;/** * 流式布局 https://github.com/hongyangAndroid/FlowLayout * * Change by mChenys on 2019/1/8. * 修改后,支持行数限制,优化了在onLayout的时候的二次循环初始化参数,支持获取当前可见的item个数 */public class FlowLayout extends ViewGroup { private static final String TAG = "FlowLayout"; protected static final int LEFT = -1; protected static final int CENTER = 0; protected static final int RIGHT = 1; protected List> mAllViews = new ArrayList>();//记录所有行 protected List mLineHeight = new ArrayList();//记录所有行高 protected List mLineWidth = new ArrayList();//记录所有行宽 protected List lineViews = new ArrayList<>();//临时记录每行的view protected int mGravity; private int maxLine = -1;//最大行数 private boolean isExceedingMaxLimit; //预设的子View是否超出了最大行数限制 public void setMaxLine(int maxLine) { this.maxLine = maxLine; } public FlowLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); mGravity = LEFT; } public FlowLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public FlowLayout(Context context) { this(context, null); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { mAllViews.clear();//记录所有行的view mLineHeight.clear();//记录每一行的高度 mLineWidth.clear();//记录每一行的宽度 lineViews.clear();//记录每一行的view isExceedingMaxLimit=false; int sizeWidth = MeasureSpec.getSize(widthMeasureSpec); int modeWidth = MeasureSpec.getMode(widthMeasureSpec); int sizeHeight = MeasureSpec.getSize(heightMeasureSpec); int modeHeight = MeasureSpec.getMode(heightMeasureSpec); // wrap_content 最终宽高 int width = 0; int height = 0; //当前已用行宽高 int lineWidth = 0; int lineHeight = 0; int cCount = getChildCount(); for (int i = 0; i < cCount; i++) { View child = getChildAt(i); if (child.getVisibility() == View.GONE) { continue; } //测量子view measureChild(child, widthMeasureSpec, heightMeasureSpec); MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); //子View宽高 int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; int childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin; if (lineWidth + childWidth > sizeWidth - getPaddingLeft() - getPaddingRight()) { if (maxLine > 0 && mAllViews.size() + 1 >= maxLine) { //+1是因为后面还有最后一行 isExceedingMaxLimit = true; break;//超过最大行数跳出循环 } //需要换行 if (i == 0 && width == 0 && lineWidth == 0 && height == 0 && lineHeight == 0) { //如果第一个子View就满足换行条件,那么width和height就是子View的宽高 width = lineWidth = childWidth; height = lineHeight = childHeight; lineViews.add(child); } else { width = Math.max(width, lineWidth);//记录最大行宽 height += lineHeight;//累加包裹内容所需的高度 } //换行前,保存当前行数据 mLineHeight.add(lineHeight); mLineWidth.add(lineWidth); mAllViews.add(lineViews); //换行,新行数据初始化 lineWidth = 0;//重新赋值行宽 lineHeight = 0;//重新赋值行高 lineViews = new ArrayList();//创建新行 if (i == 0 && width > 0 && height > 0) { //如果第一个子View就满足换行条件并且数据已经保存,则不需要下面重复添加了 continue; } } //新行或者当前行继续添加子View lineWidth += childWidth;//累加行宽 lineHeight = Math.max(lineHeight, childHeight);//取当前行最大高度作为行高 lineViews.add(child); } //添加最后一行数据 width = Math.max(lineWidth, width);//包裹内容所需的最大宽度 height += lineHeight;//累加高度 mLineHeight.add(lineHeight); mLineWidth.add(lineWidth); mAllViews.add(lineViews); setMeasuredDimension( //父控件宽高确定则用确定的,否则用测量后的 modeWidth == MeasureSpec.EXACTLY ? sizeWidth : width + getPaddingLeft() + getPaddingRight(), modeHeight == MeasureSpec.EXACTLY ? sizeHeight : height + getPaddingTop() + getPaddingBottom()// ); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { //总宽 int width = getWidth(); //当前已用行宽高 int lineHeight = 0; //下面是对每一行的View进行布局 int left = getPaddingLeft(); int top = getPaddingTop(); int lineNum = mAllViews.size(); for (int i = 0; i < lineNum; i++) { //获取当前行和行高 lineViews = mAllViews.get(i); lineHeight = mLineHeight.get(i); // set gravity int currentLineWidth = this.mLineWidth.get(i); switch (this.mGravity) { case LEFT: left = getPaddingLeft(); break; case CENTER: left = (width - currentLineWidth) / 2 + getPaddingLeft(); break; case RIGHT: // 适配了rtl,需要补偿一个padding值 ,从右边向左开始布局 left = width - (currentLineWidth + getPaddingLeft()) - getPaddingRight(); // 适配了rtl,需要把lineViews里面的数组倒序排,从右边开始存放view Collections.reverse(lineViews); break; } //开始布局 for (int j = 0; j < lineViews.size(); j++) { View child = lineViews.get(j); if (child.getVisibility() == View.GONE) { continue; } MarginLayoutParams lp = (MarginLayoutParams) child .getLayoutParams(); int childWidth=0; //超过了一行,超过显示 ...省略号 if(maxLine==1&&i==0&&isExceedingMaxLimit&&j==lineViews.size()-1&&j!=0){ childWidth=DisplayUtils.dp2px(getContext(),35); TextView textView= child.findViewById(R.id.flowLayout_text); FrameLayout.LayoutParams layoutParams= (FrameLayout.LayoutParams) textView.getLayoutParams(); layoutParams.width=DisplayUtils.dp2px(getContext(),25); textView.setLayoutParams(layoutParams); textView.setText("..."); child.measure(childWidth,child.getMeasuredHeight());//重新测量 postInvalidate();//刷新视图 }else{ childWidth=child.getMeasuredWidth(); }// int childWidth=child.getMeasuredWidth(); int lc = left + lp.leftMargin; int tc = top + lp.topMargin; int rc = lc + childWidth; int bc = tc + child.getMeasuredHeight(); child.layout(lc, tc, rc, bc);//布置child 位置 //更新下一个view添加到当前行的left left += childWidth + lp.leftMargin + lp.rightMargin; } //更新下一个view添加到下一行的top top += lineHeight;// if(i==lineNum-1){// for (int j = 0; j < mAllViews.size(); j++) {// Log.d("MyInfo","FlowLayout:"+mAllViews.size()+",line size:"+mAllViews.get(i).size());// }// } } } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); } @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { return new MarginLayoutParams(getContext(), attrs); } @Override protected LayoutParams generateDefaultLayoutParams() { return new MarginLayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); } @Override protected LayoutParams generateLayoutParams(LayoutParams p) { return new MarginLayoutParams(p); } /** * 获取指定行数内的item个数 * * @return 每行的个数之和 * @lineNum 总行数 */ public int getTotalByLine(int lineNum) { int count = 0; if (lineNum <= mAllViews.size()) { for (int i = 0; i < lineNum; i++) { List line = mAllViews.get(i); count += line.size(); } } else { for (int i = 0; i < mAllViews.size(); i++) { List line = mAllViews.get(i); count += line.size(); } } return count; } /** * 返回总行数 * * @return */ public int getTotalLine() { return mAllViews.size(); } /** * 设置的数据是否超过了最大限制 * * @return */ public boolean isExceedingMaxLimit() { return isExceedingMaxLimit; }}
使用也比较简单:
//设置标签 List labelList=model.getTagList(); if(labelList!=null&&labelList.size()>0){ flv_labelType.removeAllViews(); flv_labelType.setMaxLine(1);//设置最大显示一行 for (int i = 0; i < labelList.size(); i++) { View view = View.inflate(mContext, R.layout.item_flow_layout, null); TextView skillText = (TextView) view.findViewById(R.id.flowLayout_text); skillText.setText(labelList.get(i).getName()); flv_labelType.addView(view); } }
xml布局:
<?xml version="1.0" encoding="utf-8"?>
更多相关文章
- “罗永浩抖音首秀”销售数据的可视化大屏是怎么做出来的呢?
- Nginx系列教程(三)| 一文带你读懂Nginx的负载均衡
- 不吹不黑!GitHub 上帮助人们学习编码的 12 个资源,错过血亏...
- Android(安卓)Mediascanner实现机制
- android上传图片到服务器(使用base64字节流的形式通过 AsyncHttpC
- 【Android(安卓)界面效果49】RecyclerView高度随Item自适应
- java/Android(安卓)error系列01: Value of type org.json.JSONOb
- 在Android上使用ZXing识别条码 二次开发笔记 (2)
- Spinner的使用方法