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布局: