93:ViewDragHelper的用法,可以任意拖动view的帮助类
public class DragLayout extends LinearLayout {
private ViewDragHelper mDragHelper;
private View mDragView;
private ImageView mImageView;
private TextView mTextView;
public DragLayout(Context context) {
this(context, null);
}
public DragLayout(Context context, AttributeSet attrs) {
this(context, null, 0);
}
public DragLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
Log.e("TAG", "init3");
initView();
}
//这里一定要在渲染完成后才能实例化控件对象,否则返回的时空的值!
@Override
protected void onFinishInflate() {
mImageView = (ImageView) findViewById(R.id.imageview);
mTextView = (TextView) findViewById(R.id.text);
mDragView = mImageView;
//mDragView=mTextView;
}
//初始化数据
private void initView() {
setOrientation(LinearLayout.VERTICAL);
//实例化DragHelper对象
mDragHelper = ViewDragHelper.create(this, new DragHelperCallback());
//设置手指点击到到左侧边缘时有onEdgeTouched方法回调
mDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
//设置手指点到到右侧边时有onEdgeTouched方法回调
// mDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_RIGHT);
//这里还很设置上边和底部,或EDGRE_ALL表示所有的边缘
//mDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_ALL);
}
//事件拦截处理,基本是固定的格式
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
//final int action = MotionEventCompat.getActionMasked(ev);
if (ev.getAction() == MotionEvent.ACTION_CANCEL || ev.getAction() == MotionEvent.ACTION_UP) {
mDragHelper.cancel();
return false;
}
return mDragHelper.shouldInterceptTouchEvent(ev);
}
//事件处理,格式也是固定的
@Override
public boolean onTouchEvent(MotionEvent ev) {
// getChildAt(0).onTouchEvent(ev);
mDragHelper.processTouchEvent(ev);
return true;
}
@Override
public void computeScroll() {
if (mDragHelper.continueSettling(true)) {
postInvalidate();//注意此处.
}
}
//创建DragHelper的Callback类
class DragHelperCallback extends ViewDragHelper.Callback {
//注意必须重写了如下两个方法中的一个,才能让子view既能响应单击事件,又能拖动,这两个方法返回大于0的值子view才能正常的捕获
@Override
public int getViewHorizontalDragRange(@NonNull View child) {
return 1;
}
/* @Override
public int getViewVerticalDragRange(@NonNull View child) {
return 1;
}*/
//重写方法,格式也是固定,
//tryCaptureView方法的返回值可以决定一个parentview中哪个子view可以拖动
@Override
public boolean tryCaptureView(View child, int pointerId) {
//SnapHelper
Log.e("TAG", "mDragView == child " + (mDragView == child));
return true;//不返回true就不会被移动
//如果这里有多个View的话,返回值改变成 return child == mDragView1;
//那么只有MDragView1可以被拖拽,其他View不能
}
//如果要实现可以横向拖动,就要重写这个方法clampViewPositionHorizontal,否则默认返回的值为0
/*处理横向的拖动:
在DragHelperCallback中实现clampViewPositionHorizontal方法,
并且返回一个适当的数值就能实现横向拖动效果,
clampViewPositionHorizontal的第二个参数是指当前拖动子view应该到达的x坐标。
所以按照常理这个方法原封返回第二个参数就可以了,
但为了让被拖动的view遇到边界之后就不在拖动,对返回的值做了更多的考虑。*/
//释放的时候, 会回调下面的方法
@Override
public void onViewReleased(@NonNull View releasedChild, float xvel, float yvel) {
mDragHelper.settleCapturedViewAt(0, 100);//参数就是x,y的坐标
postInvalidate();
}
@Override
public int clampViewPositionHorizontal(View child, int left, int dx) {
Log.e("DragLayout", "clampViewPositionHorizontal " + left + "," + dx);
final int leftBound = getPaddingLeft();
final int rightBound = getWidth() - mDragView.getWidth();
final int newLeft = Math.min(Math.max(left, leftBound), rightBound);
/*if (child.getId() == R.id.imageview) {
Toast.makeText(getContext(), "点击到图片了", Toast.LENGTH_SHORT).show();
}*/
return newLeft;
}
//同样要实现纵向移动要实现这个方法
@Override
public int clampViewPositionVertical(View child, int top, int dy) {
final int topBound = getPaddingTop(); //padding顶部的距离
//父框体的宽度减去视图本身的宽度,得到可以移动的最大宽度
final int bottomBound = getHeight() - mDragView.getHeight();
//先取出padding顶部和距离顶部距离的最大值
//然后让这个最大值和这个视图可以移动的距离做比较,取出最小值,得到视图实际可以移动的距离
final int newTop = Math.min(Math.max(top, topBound), bottomBound);
return newTop;
}
//重写处理视图滑动到边缘时的事件
//如果上面设置了mDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_...);下面的方法才会得到回调
//没有得到回调的原因???
//这里滑动到边缘是指手指在容器的边缘滑动,而不是指把指View拖动到边缘时触发
@Override
public void onEdgeTouched(int edgeFlags, int pointerId) {
Log.e("TAG", "滑动到左边或右边了");
super.onEdgeTouched(edgeFlags, pointerId);
Toast.makeText(getContext(), "点击到左边了", Toast.LENGTH_SHORT).show();
}
/* 如果你想在边缘滑动的时候根据滑动距离移动一个子view,
可以通过实现onEdgeDragStarted方法,
并在onEdgeDragStarted方法中手动指定要移动的子View*/
@Override //不太理解!
public void onEdgeDragStarted(int edgeFlags, int pointerId) {
Log.e("TAG", "滑onEdgeDragStarted了");
//mDragHelper.captureChildView(mDragView, pointerId);
}
}
}
参考网址:
https://blog.csdn.net/wenzhi20102321/article/details/60156908
https://www.jianshu.com/p/d78515acb4c6
https://blog.csdn.net/lmj623565791/article/details/46858663
94:DatePickerDialog的用法
https://www.cnblogs.com/huanyou/p/5087044.html
95:比较两个Drawable对象是否一样的方式:(已记录)
if (gridView.getChildAt(i).findViewById(R.id.kaoshi_adapter_textview).getBackground().getConstantState()
== getResources().getDrawable(R.drawable.yuanxing).getConstantState()) {
Toast.makeText(this, "请先完成第" + i + "道题!", Toast.LENGTH_SHORT).show();
break;
}
https://blog.csdn.net/wen386089/article/details/38019623
96:在使用bmob时如果是客户端写多表查询,千万不要只用list进行多次for循环,要用hashmap,另外hashmap如果remove一个数据后,这个数据的位置就成了null了,不会被后面的数据顶上来,remove方法是用key来找value的,另外values方法可以得到hashmap中的所有值。
List kaoShiEntityList = new ArrayList<>();
ArrayMap hashMap = new ArrayMap<>();
for (KaoShiEntity kaoShiEntity : (List) list) {
hashMap.put(kaoShiEntity.getExamId(), kaoShiEntity);
}
for (AlreadyExamEntity alreadyExamEntity : (List) list2) {
if (hashMap.containsKey(alreadyExamEntity.getExamId())) {
hashMap.remove(alreadyExamEntity.getExamId());
}
}
for (KaoShiEntity kaoShiEntity : hashMap.values()) {
for (TiKuEntity tiKuEntity : (List) list1) {
if (tiKuEntity.getName().equals(kaoShiEntity.getExamClass())) {
kaoShiEntityList.add(new KaoShiEntity(kaoShiEntity, tiKuEntity.getClassimg().getUrl()));
break;
}
}
}
/* try {
for (int i = 0; i < totalHashCount; i++) {
for (TiKuEntity tiKuEntity : (List) list1) {
if (hashMap.get(i) != null) {
if (tiKuEntity.getName().equals(hashMap.get(i).getExamClass())) {
kaoShiEntityList.add(new KaoShiEntity(hashMap.get(i), tiKuEntity.getClassimg().getUrl()));
break;
}
} else
break;
}
}
} catch (Exception e) {
Log.e("Exception", "response: " + e.getMessage());
}*/
/* for (KaoShiEntity kaoShiEntity : (List) list) {
for (AlreadyExamEntity alreadyExamEntity : (List) list2) {
for (TiKuEntity tiKuEntity : (List) list1) {
Log.e("loadData", "kaoShiEntity.getExamClass():" + kaoShiEntity.getExamClass() + ",tiKuEntity.getName():" + tiKuEntity.getName() +
",alreadyExamEntity.getExamId():" + alreadyExamEntity.getExamId() + ",kaoShiEntity.getExamId()" + kaoShiEntity.getExamId());
if (kaoShiEntity.getExamClass().equals(tiKuEntity.getName()) && alreadyExamEntity.getExamId() != kaoShiEntity.getExamId()) {
for (int i = 0; i < kaoShiEntityList.size(); i++) {
if (kaoShiEntityList.get(i).getExamId() != kaoShiEntity.getExamId()) {
}
}
kaoShiEntityList.add(new KaoShiEntity(kaoShiEntity, tiKuEntity.getClassimg().getUrl()));
Log.e("loadData222", "kaoShiEntity.getExamClass():" + kaoShiEntity.getExamClass() + ",tiKuEntity.getName():" + tiKuEntity.getName() +
",alreadyExamEntity.getExamId():" + alreadyExamEntity.getExamId() + ",kaoShiEntity.getExamId()" + kaoShiEntity.getExamId());
}
}
}
}*/
if (kaoShiEntityList.size() != 0)
view.addGridData(kaoShiEntityList);
97:属性动画,记得给ValueAnimator设置Evaluator,动画才能有过渡效果
ValueAnimator valueAnimator = new ValueAnimator();
valueAnimator.setEvaluator(new IntEvaluator());
valueAnimator.setIntValues(ScreenUtils.getScreenHeight(LoginActivity.this) / 2, ScreenUtils.getScreenHeight(LoginActivity.this) - ConvertUtils.dp2px(LoginActivity.this, 80));
valueAnimator.setDuration(1000);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
dengLuLinearLayout.getLayoutParams().height = (int) animation.getAnimatedValue();
dengLuLinearLayout.requestLayout();
}
});
valueAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
weiZhuCe.setVisibility(View.INVISIBLE);
zhuCeImageView.setVisibility(View.INVISIBLE);
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
valueAnimator.start();
/* zhuCeLinearLayout.animate().withStartAction(new Runnable() {
@Override
public void run() {
weiZhuCe.setVisibility(View.INVISIBLE);
zhuCeImageView.setVisibility(View.INVISIBLE);
ValueAnimator valueAnimator = new ValueAnimator();
valueAnimator.setEvaluator(new IntEvaluator());
valueAnimator.setIntValues(ScreenUtils.getScreenHeight(LoginActivity.this) - 80);
valueAnimator.setDuration(1000);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
dengLuLinearLayout.getLayoutParams().height= (int) animation.getAnimatedValue();
dengLuLinearLayout.requestLayout();
}
});
valueAnimator.start();
}
}).y(ScreenUtils.getScreenHeight(this) - ConvertUtils.dp2px(this, 80)).setDuration(1000).withEndAction(new Runnable() {
@Override
public void run() {
}
}).start();*/
98:Android 自定义Switch开关按钮的样式
https://www.jianshu.com/p/4e436300f328
99:item设置的高度和宽度不起作用
https://www.cnblogs.com/cheneasternsun/p/6080683.html
100:Android 中webview载入网页总是跳到浏览器
https://ask.csdn.net/questions/178242
101:多个webview的后退
/**
* 退出
*/
@Override
public void onBackPressed() {
if (fragment.getHomeViewpager().getCurrentItem() != 0) {
if ((((WebFragment) fragment.getList().get(fragment.getHomeViewpager().getCurrentItem())).getWebView().canGoBack())) {
((WebFragment) fragment.getList().get(fragment.getHomeViewpager().getCurrentItem())).getWebView().goBack();
} else {
exitAPP();
}
return;
}
exitAPP();
}
private void exitAPP() {
long secondTime = System.currentTimeMillis();
if (secondTime - firstTime > 2000) {
ActivityUtils.showToast(this, "再按一次退出程序");
firstTime = secondTime;
} else {
finish();
MobclickAgent.onKillProcess(this);
overridePendingTransition(R.anim.exit_enter, R.anim.exit_out);
MyApplication.exit(this);
}
}
102:Android加载本地静态网页(静态网页的图片也放在assets文件夹下就行)
https://blog.csdn.net/gisuuser/article/details/77721312
https://blog.csdn.net/m0_37402140/article/details/78640023
103:Android:你要的WebView与 JS 交互方式 都在这里了
https://blog.csdn.net/carson_ho/article/details/64904691/
104:android中两个日期相减
if (Integer.parseInt(cha.split("天")[0]) == 0) {
if (cha.split("天")[1].startsWith("0小时"))
holder_one_image.riqi.setText(cha.split("天")[1].substring(3) + "前");
else
holder_one_image.riqi.setText(cha.split("天")[1] + "前");
} else
holder_one_image.riqi.setText(list.get(position).getCreate_date().split(" ")[0]);
https://blog.csdn.net/hang916/article/details/79154873
https://blog.csdn.net/mp624183768/article/details/81060052
105:在使用友盟间接用微信账号登录app时,记得把包名改的和云端一样,并不只是applicationId而已,另外就是如果用一个微信号登录失败后,就又用另外一个微信号登录了,不然会一直都是报错的,微信反应不过来。
106:Android 第三方应用跳转到qq进行聊天(qq咨询),不能用,发不出消息去
https://blog.csdn.net/jyz_2015/article/details/51669079
107:bmob中,实体类的类名就是数据库的表名,实体类的字段名就是数据库对应表中的列名,必须完全一样,才能收到数据。
108:bomb更新部分数据的时候记得连主键一起更新,不然的话,主键会被还原成初始值,不是主键可以不用更新,只更新需要更新的数据即可。
public void updateUserEntityList(String userData, String objectId) {
String[] datas = userData.split("~");
UserEntity userEntity = new UserEntity(datas[2], datas[4], datas[3], datas[1]);
if (datas[0].equals("学生"))
userEntity.setIdentity(0);
else if (datas[0].equals("老师"))
userEntity.setIdentity(1);
else if (datas[0].equals("管理员"))
userEntity.setIdentity(2);
userEntity.setUserId(MyApplication.userId);//userId是主键,所以也得更新
userEntity.update(objectId, new UpdateListener() {
@Override
public void done(BmobException e) {
if (e == null) {
Toast.makeText(MyApplication.myApplication, "提交成功", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MyApplication.myApplication, "提交失败", Toast.LENGTH_SHORT).show();
}
}
});
}
109:这个自定义圆形头像框好用,可以设置边框线
package com.doding.dogtraining.views;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;
/**
* Created by qiang on 2019/3/1.
*/
public class Mine_ImageViewPlus extends ImageView {
private Paint mPaintBitmap = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint mPaintBorder = new Paint(Paint.ANTI_ALIAS_FLAG);
private Bitmap mRawBitmap;
private BitmapShader mShader;
private Matrix mMatrix = new Matrix();
private float mBorderWidth = dip2px(0);
private int mBorderColor = 0x80bebebe;
public Mine_ImageViewPlus(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
Bitmap rawBitmap = getBitmap(getDrawable());
if (rawBitmap != null){
int viewWidth = getWidth();
int viewHeight = getHeight();
int viewMinSize = Math.min(viewWidth, viewHeight);
float dstWidth = viewMinSize;
float dstHeight = viewMinSize;
if (mShader == null || !rawBitmap.equals(mRawBitmap)){
mRawBitmap = rawBitmap;
mShader = new BitmapShader(mRawBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
}
if (mShader != null){
mMatrix.setScale((dstWidth - mBorderWidth * 2) / rawBitmap.getWidth(), (dstHeight - mBorderWidth * 2) / rawBitmap.getHeight());
mShader.setLocalMatrix(mMatrix);
}
mPaintBitmap.setShader(mShader);
mPaintBorder.setStyle(Paint.Style.STROKE);
mPaintBorder.setStrokeWidth(mBorderWidth);
mPaintBorder.setColor(mBorderColor);
float radius = viewMinSize / 2.0f;
canvas.drawCircle(radius, radius, radius - mBorderWidth / 2.0f, mPaintBorder);
canvas.translate(mBorderWidth, mBorderWidth);
canvas.drawCircle(radius - mBorderWidth, radius - mBorderWidth, radius - mBorderWidth, mPaintBitmap);
} else {
super.onDraw(canvas);
}
}
private Bitmap getBitmap(Drawable drawable){
if (drawable instanceof BitmapDrawable){
return ((BitmapDrawable)drawable).getBitmap();
} else if (drawable instanceof ColorDrawable){
Rect rect = drawable.getBounds();
int width = rect.right - rect.left;
int height = rect.bottom - rect.top;
int color = ((ColorDrawable)drawable).getColor();
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawARGB(Color.alpha(color), Color.red(color), Color.green(color), Color.blue(color));
return bitmap;
} else {
return null;
}
}
private int dip2px(int dipVal) {
float scale = getResources().getDisplayMetrics().density;
return (int)(dipVal * scale + 0.5f);
}
}
110:HashMap中如果两个数据的key和value都一样,那么HashMap只会保存其中的一个数据。
111:比较两个两个字符串的相似程度
https://blog.csdn.net/lyl0724/article/details/72819780?utm_source=blogxgwz0
112:Android中Math取整的三个方法
https://blog.csdn.net/zhangxmu/article/details/49558549
113:将网页的源代码中的去掉,然后用Android的webview加载之后,初始显示出来的网页是没有放大的。
114:将序列化后的实体类保存到本地的方法(已记录)
public class WriteFileHelper {
private String fileName;
public WriteFileHelper(String fileName) {
this.fileName = fileName;
}
public void saveObjToFile(Parcelable parcelable) throws IOException {
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(fileName));
objectOutputStream.writeObject(parcelable);
objectOutputStream.close();
}
public Parcelable getObjFromFile() throws IOException, ClassNotFoundException {
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(fileName));
Parcelable parcelable = (UserDataEntity) objectInputStream.readObject();
objectInputStream.close();
return parcelable;
}
}
public class UserDataEntity implements Parcelable ,Serializable{
private String isHaveDog;
private String dogType;
private String dogSex;
private String dogAge;
private String careQuestions;
@Override
public String toString() {
return "UserDataEntity{" +
"isHaveDog='" + isHaveDog + '\'' +
", dogType='" + dogType + '\'' +
", dogSex='" + dogSex + '\'' +
", dogAge='" + dogAge + '\'' +
", careQuestions='" + careQuestions + '\'' +
'}';
}
public String getIsHaveDog() {
return isHaveDog;
}
public void setIsHaveDog(String isHaveDog) {
this.isHaveDog = isHaveDog;
}
public String getDogType() {
return dogType;
}
public void setDogType(String dogType) {
this.dogType = dogType;
}
public String getDogSex() {
return dogSex;
}
public void setDogSex(String dogSex) {
this.dogSex = dogSex;
}
public String getDogAge() {
return dogAge;
}
public void setDogAge(String dogAge) {
this.dogAge = dogAge;
}
public String getCareQuestions() {
return careQuestions;
}
public void setCareQuestions(String careQuestions) {
this.careQuestions = careQuestions;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.isHaveDog);
dest.writeString(this.dogType);
dest.writeString(this.dogSex);
dest.writeString(this.dogAge);
dest.writeString(this.careQuestions);
}
public UserDataEntity() {
}
protected UserDataEntity(Parcel in) {
this.isHaveDog = in.readString();
this.dogType = in.readString();
this.dogSex = in.readString();
this.dogAge = in.readString();
this.careQuestions = in.readString();
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
@Override
public UserDataEntity createFromParcel(Parcel source) {
return new UserDataEntity(source);
}
@Override
public UserDataEntity[] newArray(int size) {
return new UserDataEntity[size];
}
};
}
https://blog.csdn.net/zhangjin123go/article/details/84911239
115:BaseAdapter的getViewTypeCount和getItemViewType的用法,getItemViewType会在getView前面调用,提前给view打上标签,另外就是只有当列表的item从屏幕中消失之后,再出现才会调用适配器的视图复用,如果列表的所有的item都在屏幕中,可以放的下,就不会调用视图复用,视图复用是指当下一个item中没有任何变化的话,那么此item中的内容还是上一个的,如果有一点改动,那么该item中的所有view都会清空缓存,还有就是如果一个适配器有多种布局或者是布局的视图有变化的话(比如把一个布局中某个view隐藏或显示),也要用到getViewTypeCount和getItemViewType,另外注意不能在适配器中动态添加视图,不然布局会乱,如果是某个视图中的某个view中的内容需要发生改变(比如给textview设置值),就需要从数据层面来修改,就不用那两个方法(getViewTypeCount和getItemViewType)了,具体的视图变化逻辑还是写在getView方法中,getItemViewType会在getView方法执行之前执行,所有要在getItemViewType中进行限制,如果在getView方法中进行限制的话,一旦出现异常,item的布局就乱了,还有一个注意的地方就是item的视图中如果出现图片,要给图片的宽和高设置具体的大小,而不是用layout_weight来设置,如果用layout_weight来设置的话会出现各种奇葩现象,代码如下:
public class ZuixinListviewAdapter_One extends BaseAdapter {
private Context context;
private List list;
public ZuixinListviewAdapter_One(List list, Context context) {
this.list = list;
this.context = context;
}
@Override
public int getCount() {
if (list == null) {
return 0;
}
return list.size();
}
@Override
public Object getItem(int i) {
return i;
}
@Override
public int getViewTypeCount() {
return 2;
}
@Override
public int getItemViewType(int position) {
if(list.get(position).isAd())
return 0;
else
return 1;
}
@Override
public long getItemId(int i) {
return i;
}
@SuppressLint("InflateParams")
@Override
public View getView(int position, View view, ViewGroup viewGroup) {
switch (getItemViewType(position)){
case 0:
view = LayoutInflater.from(context).inflate(R.layout.aditem,
viewGroup, false);
LinearLayout linearLayout = view.findViewById(R.id.lin);
Utils utils = new Utils();
utils.setADDate((Activity) context, linearLayout);
final View finalView = view;
new Thread(new Runnable() {
@Override
public void run() {
try {
String response = MainActivity.sendGetRequest("https://xcx.51babyapp.com/dog/ad1");
if (!response.equals("{}")) {
final JSONObject jsonObject = new JSONObject(response);
((Activity) context).runOnUiThread(new Runnable() {
@Override
public void run() {
try {
Glide.with(context).load(jsonObject.getString("pictures_url")).into((ImageView) finalView.findViewById(R.id.aditem_img));
((TextView) finalView.findViewById(R.id.aditem_text)).setText(jsonObject.getString("ad1"));
MyApplication.adYu = jsonObject.getString("ad1");
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
break;
case 1:
try {
ViewHolder_one_image holder_one_image = null;
if (list.get(position).isAd()) {
} else {
if (view == null) {
view = LayoutInflater.from(context).inflate(R.layout.viewpagerfirsthomezuixinfragmentitme_one_image,
viewGroup, false);
holder_one_image = new ViewHolder_one_image();
holder_one_image.title = (TextView) view.findViewById(R.id.title);
holder_one_image.shoucang = (TextView) view.findViewById(R.id.shoucang);
holder_one_image.liulan = (TextView) view.findViewById(R.id.liulan);
holder_one_image.dianzan_image = (ImageView) view.findViewById(R.id.dianzan_image);
holder_one_image.one_image = (ImageView) view.findViewById(R.id.one_image);
holder_one_image.riqi = (TextView) view.findViewById(R.id.riqi);
holder_one_image.guanfang = (TextView) view.findViewById(R.id.guanfang);
holder_one_image.touxiang = (Mine_ImageViewPlus) view.findViewById(R.id.touxiang);
holder_one_image.biaoqian = (TextView) view.findViewById(R.id.biaoqian);
holder_one_image.xuanquanname = (TextView) view.findViewById(R.id.xuanquanname);
view.setTag(holder_one_image);
} else {
holder_one_image = (ViewHolder_one_image) view.getTag();
}
Glide.with(context).load(MyApplication.head_url).into(holder_one_image.touxiang);
holder_one_image.xuanquanname.setText(MyApplication.name);
holder_one_image.title.setText(list.get(position).getArticle_name().trim());
holder_one_image.guanfang.setText("官方");
holder_one_image.liulan.setText(list.get(position).getLiulancount() + "浏览");
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date(System.currentTimeMillis());
String cha = TimeDifferenceUtils.getTimeDifference(df.format(date), list.get(position).getCreate_date());
if (Integer.parseInt(cha.split("天")[0]) == 0) {
if (cha.split("天")[1].startsWith("0小时"))
holder_one_image.riqi.setText(cha.split("天")[1].substring(3) + "前");
else
holder_one_image.riqi.setText(cha.split("天")[1] + "前");
} else
holder_one_image.riqi.setText(list.get(position).getCreate_date().split(" ")[0]);
if (!list.get(position).getPictures_url().equals("")) {
//RequestOptions requestOptions = RequestOptions.centerCropTransform().optionalTransform(new MyTransition(context));
Glide.with(context).load(list.get(position).getPictures_url())
.into(holder_one_image.one_image);
}
holder_one_image.shoucang.setText((list.get(position).getShoucangcount() + "收藏"));
}
} catch (Exception e) {
Log.e("ViewHolder_one_image", "getView: " + e);
}
break;
}
return view;
}
class ViewHolder_one_image {
Mine_ImageViewPlus touxiang;
TextView title, shoucang, liulan, riqi, biaoqian, xuanquanname, guanfang;
ImageView dianzan_image, one_image;
}
}
再来一例:
public class Work_Heng_Random_Ge_GridView_Two_Adapter extends BaseAdapter {
List list;
Context context;
public Work_Heng_Random_Ge_GridView_Two_Adapter(List list, Context context) {
this.list = list;
this.context = context;
}
@Override
public int getCount() {
return list.size();
}
@Override
public int getItemViewType(int position) {
int biao = 0;
switch (list.get(position).getBiaoShi()) {
case 0:
biao = 0;
break;
case 1:
biao = 1;
break;
case 2:
biao = 2;
break;
}
return biao;
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getViewTypeCount() {
return 3;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
switch (getItemViewType(position)) {
case 0:
try {
GridViewViewHolder gridViewViewHolder = null;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.adapter_heng_random_ge_gridview_two_item, null);
gridViewViewHolder = new GridViewViewHolder();
gridViewViewHolder.image = convertView.findViewById(R.id.adapter_grid_two_image);
gridViewViewHolder.title = convertView.findViewById(R.id.adapter_grid_two_title);
gridViewViewHolder.pingFen = convertView.findViewById(R.id.adapter_grid_two_pingfen);
gridViewViewHolder.lin = convertView.findViewById(R.id.lin);
convertView.setTag(gridViewViewHolder);
} else {
gridViewViewHolder = (GridViewViewHolder) convertView.getTag();
}
Glide.with(context).load(Utils.tupianurl + list.get(position).getImg_url()).into(gridViewViewHolder.image);
gridViewViewHolder.title.setText(list.get(position).getClass_name());
gridViewViewHolder.pingFen.setText(list.get(position).getScore());
} catch (Exception e) {
Log.e("convertView", "getView: " + e.getMessage());
}
break;
case 1:
convertView = LayoutInflater.from(context).inflate(R.layout.adapter_heng_random_ge_gridview_two_item1, null);
break;
case 2:
GridViewViewHolder_One g = new GridViewViewHolder_One();
convertView = LayoutInflater.from(context).inflate(R.layout.adapter_heng_random_ge_gridview_two_item2, null);
g.textView = convertView.findViewById(R.id.text);
g.textView.setText(list.get(position).getWenBen());
break;
}
return convertView;
}
private class GridViewViewHolder {
TextView title, pingFen;
ImageView image;
LinearLayout lin;
}
private class GridViewViewHolder_One {
TextView textView;
}
}
116:Android--Alertdialog对话框,设置点击其他位置不消失
https://blog.csdn.net/coderCui/article/details/77742931
117:如何使用友盟统计(自定义事件)
https://blog.csdn.net/mp624183768/article/details/78578656
118:当listview快滚动到底部的时候,会自动加载更多,代码如下:
private int firstItem;
private int totalItem;
...
listView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
Log.e("onScroll", "onScrollStateChanged: " + scrollState + ",firstItem:" + firstItem + ",totalItem:" + totalItem);
if (scrollState == 0) {
if (totalItem - firstItem < 12) {
load_more();
}
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
firstItem = firstVisibleItem;
totalItem = totalItemCount;
Log.e("onScroll", "firstVisibleItem:" + firstVisibleItem + ",visibleItemCount:" + visibleItemCount + ",totalItemCount:" + totalItemCount);
}
});
119:bmob上传头像
https://blog.csdn.net/wy_is_learning/article/details/73692852
120:List的排序
Collections.sort(arrayList, new Comparator() {
@Override
public int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);
}
});
https://blog.csdn.net/xHibiki/article/details/82938480
121:如果要改变适配器的样式和逻辑,必须从数据层面入手改,如果直接在getview方法中改的话,会出现各种奇葩情况,完美的代码如下:
public class ZuixinListviewAdapter_One extends BaseAdapter {
private Context context;
private List list;
public ZuixinListviewAdapter_One(List list, Context context) {
this.list = list;
this.context = context;
}
@Override
public int getCount() {
if (list == null) {
return 0;
}
return list.size();
}
@Override
public Object getItem(int i) {
return i;
}
@Override
public int getViewTypeCount() {
return 2;
}
@Override
public int getItemViewType(int position) {
if (list.get(position).isAd())
return 0;
else
return 1;
}
@Override
public long getItemId(int i) {
return i;
}
@SuppressLint("InflateParams")
@Override
public View getView(int position, View view, ViewGroup viewGroup) {
switch (getItemViewType(position)) {
case 0:
ViewHolder_two_image holder_one_image1 = null;
if (view == null) {
view = LayoutInflater.from(context).inflate(R.layout.aditem,
viewGroup, false);
holder_one_image1 = new ViewHolder_two_image();
holder_one_image1.linearLayout = view.findViewById(R.id.lin);
Utils utils = new Utils();
utils.setADDate((Activity) context, holder_one_image1.linearLayout);
view.setTag(holder_one_image1);
} else {
holder_one_image1 = (ViewHolder_two_image) view.getTag();
}
final ViewHolder_two_image finalHolder_one_image = holder_one_image1;
try {
Glide.with(context).load(list.get(position).getAdImgUrl()).into((ImageView) finalHolder_one_image.linearLayout.findViewById(R.id.aditem_img));
((TextView) finalHolder_one_image.linearLayout.findViewById(R.id.aditem_text)).setText(list.get(position).getAdString());
} catch (Exception e) {
e.printStackTrace();
}
break;
case 1:
try {
ViewHolder_one_image holder_one_image = null;
if (view == null) {
view = LayoutInflater.from(context).inflate(R.layout.viewpagerfirsthomezuixinfragmentitme_one_image,
viewGroup, false);
holder_one_image = new ViewHolder_one_image();
holder_one_image.title = (TextView) view.findViewById(R.id.title);
holder_one_image.shoucang = (TextView) view.findViewById(R.id.shoucang);
holder_one_image.liulan = (TextView) view.findViewById(R.id.liulan);
holder_one_image.dianzan_image = (ImageView) view.findViewById(R.id.dianzan_image);
holder_one_image.one_image = (MyImageView) view.findViewById(R.id.one_image);
holder_one_image.riqi = (TextView) view.findViewById(R.id.riqi);
holder_one_image.guanfang = (TextView) view.findViewById(R.id.guanfang);
holder_one_image.touxiang = (Mine_ImageViewPlus) view.findViewById(R.id.touxiang);
holder_one_image.biaoqian = (TextView) view.findViewById(R.id.biaoqian);
holder_one_image.xuanquanname = (TextView) view.findViewById(R.id.xuanquanname);
view.setTag(holder_one_image);
} else {
holder_one_image = (ViewHolder_one_image) view.getTag();
}
Glide.with(context).load(MyApplication.head_url).into(holder_one_image.touxiang);
holder_one_image.xuanquanname.setText(MyApplication.name);
holder_one_image.title.setText(list.get(position).getArticle_name().trim());
holder_one_image.guanfang.setText("官方");
holder_one_image.liulan.setText(list.get(position).getLiulancount() + "浏览");
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date(System.currentTimeMillis());
String cha = TimeDifferenceUtils.getTimeDifference(df.format(date), list.get(position).getCreate_date());
if (Integer.parseInt(cha.split("天")[0]) == 0) {
if (cha.split("天")[1].startsWith("0小时"))
holder_one_image.riqi.setText(cha.split("天")[1].substring(3) + "前");
else
holder_one_image.riqi.setText(cha.split("天")[1] + "前");
} else
holder_one_image.riqi.setText(list.get(position).getCreate_date().split(" ")[0]);
if (!list.get(position).getPictures_url().equals("")) {
//RequestOptions requestOptions = RequestOptions.centerCropTransform().optionalTransform(new MyTransition(context));
Glide.with(context).load(list.get(position).getPictures_url())
.into(holder_one_image.one_image);
}
holder_one_image.shoucang.setText((list.get(position).getShoucangcount() + "收藏"));
} catch (Exception e) {
Log.e("ViewHolder_one_image", "getView: " + e);
}
break;
}
return view;
}
class ViewHolder_one_image {
Mine_ImageViewPlus touxiang;
TextView title, shoucang, liulan, riqi, biaoqian, xuanquanname, guanfang;
ImageView dianzan_image;
MyImageView one_image;
}
class ViewHolder_two_image {
LinearLayout linearLayout;
}
}
122:Android的sqlite数据库创建自增的字段及按序排列数据
db.execSQL("create table records(id integer primary key autoincrement,name varchar(200))");
...
helper.getReadableDatabase().rawQuery(
"select id as _id,name from records where name like '%" + tempName + "%' order by id desc ", null);
123:在自定义view中使用butterknife
View view = LayoutInflater.from(context).inflate(R.layout.layout_shouye_search_one, this);
ButterKnife.bind(this, view);
124:Android程序退出彻底关闭进程的方法
https://blog.csdn.net/qq953655369/article/details/72640036
125:文本右边也可以对齐的textview
public class AutoTextView extends TextView {
private int mLineY;
private int mViewWidth;
public AutoTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public AutoTextView(Context context) {
super(context);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
}
@Override
protected void onDraw(Canvas canvas) {
TextPaint paint = getPaint();
paint.setColor(getCurrentTextColor());
paint.drawableState = getDrawableState();
mViewWidth = getMeasuredWidth();
String text = getText().toString();
mLineY = 0;
mLineY += getTextSize();
Layout layout = getLayout();
for (int i = 0; i < layout.getLineCount(); i++) {
int lineStart = layout.getLineStart(i);
int lineEnd = layout.getLineEnd(i);
String line = text.substring(lineStart, lineEnd);
float width = StaticLayout.getDesiredWidth(text, lineStart, lineEnd, getPaint());
if (needScale(line)) {
drawScaledText(canvas, lineStart, line, width);
} else {
canvas.drawText(line, 0, mLineY, paint);
}
mLineY += getLineHeight();
}
}
private void drawScaledText(Canvas canvas, int lineStart, String line, float lineWidth) {
float x = 0;
if (isFirstLineOfParagraph(lineStart, line)) {
String blanks = " ";
canvas.drawText(blanks, x, mLineY, getPaint());
float bw = StaticLayout.getDesiredWidth(blanks, getPaint());
x += bw;
line = line.substring(3);
}
float d = (mViewWidth - lineWidth) / line.length() - 1;
for (int i = 0; i < line.length(); i++) {
String c = String.valueOf(line.charAt(i));
float cw = StaticLayout.getDesiredWidth(c, getPaint());
canvas.drawText(c, x, mLineY, getPaint());
x += cw + d;
}
}
private boolean isFirstLineOfParagraph(int lineStart, String line) {
return line.length() > 3 && line.charAt(0) == ' ' && line.charAt(1) == ' ';
}
private boolean needScale(String line) {
if (line.length() <15) {
return false;
} else {
return line.charAt(line.length() - 1) != '\n';
}
}
}
126:模拟点击(已记录)
float x = 100;
float y = 100;
long downTime = SystemClock.uptimeMillis();
MotionEvent downEvent = MotionEvent.obtain(downTime, downTime, MotionEvent.ACTION_DOWN, x, y, 0);
downTime += 100;
MotionEvent upEvent = MotionEvent.obtain(downTime, downTime, MotionEvent.ACTION_UP, x, y, 0);
table.dispatchTouchEvent(downEvent);
table.dispatchTouchEvent(upEvent);
downEvent.recycle();
upEvent.recycle();
模拟滑动(已记录)
float x1 = 10;
float y1 = 10;
float x2 = 100;
float y2 = 100;
long downTime = SystemClock.uptimeMillis();
MotionEvent downEvent = MotionEvent.obtain(downTime, downTime, MotionEvent.ACTION_DOWN, x1, y1, 0);
downTime += 100;
MotionEvent moveEvent = MotionEvent.obtain(downTime, downTime, MotionEvent.ACTION_MOVE, x2, y2, 0);
downTime += 100;
MotionEvent upEvent = MotionEvent.obtain(downTime, downTime, MotionEvent.ACTION_UP, x2, y2, 0);
view.dispatchTouchEvent(downEvent);
view.dispatchTouchEvent(moveEvent);
view.dispatchTouchEvent(upEvent);
downEvent.recycle();
moveEvent.recycle();
upEvent.recycle();
127:Android View简易生成Pdf
https://blog.csdn.net/weixin_40022240/article/details/80692596
128:pdf阅览器
https://github.com/barteksc/AndroidPdfViewer
129:Handler,Message,MessageQueue,Looper之间的关系:
当new一个Handler的时候,可以给Handler指定Looper,也可以不指定,如果不指定那么Handler就会从当前线程中获取Looper(也就是主线程这种情况可以,因为主线程中就有Looper,其他子线程如果不指定Looper的话就会报错),然后Handler就会运行在Looper所在的线程中,Handler通过sendMessage方法可以将Message传递到Looper的MessageQueue中,然后Looper会不停的访问MessageQueue,从MessageQueue中取出Message发送给Handler的handleMessage中,这样就实现了线程之间的通信。
线程之间的通信,大致分为两种:
主线程向子线程发送Message,主线程中自带Looper,Handler运行在主线程中,从子线程中发送Message;
子线程向主线程发送Message,需要在子线程中创建Looper,Handler运行在子线程中,从主线程中发送Message;
在子线程中创建Looper的代码如下:
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Looper.loop();
返回Looper的方法:
public Looper getLooper() {
if (!isAlive()) {
return null;
}
synchronized (this) {
while (isAlive() && mLooper == null) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
return mLooper;
}
130:Android EditText 软键盘上回车改为搜索
https://blog.csdn.net/qq_21937107/article/details/80228020
131:android 监控软键盘确定 搜索 按钮并赋予点击事件
https://blog.csdn.net/u011993368/article/details/45060429
132:Runtime类和System类
Runtime.getRuntime().totalMemory();//得到当前的内存大小
Runtime.getRuntime().availableProcessors()//获取cpu的核数
System.currentTimeMillis();//得到当前的系统时间
133:Android学习笔记之性能优化SparseArray
https://www.cnblogs.com/RGogoing/p/5095168.html
134:线程池的execute方法和submit方法的区别
execute方法没有返回值;
submit方法返回一个Future对象,内部调用了execute方法;
135:监听网络状态的改变,当用户改变网络状态后,系统会发出一个action为android.net.conn.CONNECTIVITY_CHANGE的intent
public class NetChangeBroadCast extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
NetworkInfo info = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
if (info != null) {
//如果当前的网络连接成功并且网络连接可用
if (NetworkInfo.State.CONNECTED == info.getState() && info.isAvailable()) {
if (info.getType() == ConnectivityManager.TYPE_WIFI || info.getType() == ConnectivityManager.TYPE_MOBILE) {
Log.i("TAG", info.getType() + "连上");
}
} else {
Log.i("TAG", info.getType() + "断开");
}
}
}
}
136:拼接json字符串是,双引号为",不能用单引号,代码如下:
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("{\"ask\": {");
Set strings = map.keySet();
Iterator iterable = strings.iterator();
while (iterable.hasNext()) {
String s = iterable.next();
stringBuffer.append("\"" + s + "\":");
stringBuffer.append("\"" + map.get(s) + "\",");
}
String string = stringBuffer.substring(0, stringBuffer.toString().length() - 1);
String string1 = string + "}}";
137:随机生成uuid,代码如下:
UUID uuid = UUID.randomUUID();
138:获取webview截图的方法,代码如下:
public static Bitmap captureWebView(WebView webView) {
Picture picture = webView.capturePicture();
int width = picture.getWidth();
int height = picture.getHeight();
if (width > 0 && height > 0) {
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
picture.draw(canvas);
return bitmap;
}
return null;
}
https://blog.csdn.net/u014538198/article/details/84988819
139:计时类Timer
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
timeCount++;
Log.e("timer", "run: " + timeCount);
}
}, 0, 1000);
140:让AlertDialog即使按下返回键也不会消失的方法,如下
alertDialog.setCancelable(false);
141:Android系统自带的实现倒计时的类CountDownTimer,并且该类的计时功能即使按下手机的home键,仍然会继续计时,CountDownTimer的构造方法的两个参数的单位都是毫秒:
countDownTimer = new CountDownTimer(Long.parseLong(kaoXiangQingEntity.getDuringTime()) * 1000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
Log.e("onTick", "onTick: " + millisUntilFinished);
long day = millisUntilFinished / (1000 * 24 * 60 * 60); //单位天
long hour = (millisUntilFinished - day * (1000 * 24 * 60 * 60)) / (1000 * 60 * 60); //单位时
long minute = (millisUntilFinished - day * (1000 * 24 * 60 * 60) - hour * (1000 * 60 * 60)) / (1000 * 60); //单位分
long second = (millisUntilFinished - day * (1000 * 24 * 60 * 60) - hour * (1000 * 60 * 60) - minute * (1000 * 60)) / 1000;//单位秒
jiShi.setText("剩余:" + hour + "小时" + minute + "分钟" + second + "秒");
}
@Override
public void onFinish() {
}
};
https://blog.csdn.net/mrzhao_perfectcode/article/details/81289578
141:普通的viewpager如果不设置setOffscreenPageLimit的话,当超了一定数量后,有的fragment会被重新加载,但是懒加载的fragment不会,就是我github上的那个懒加载。
142:一个可以读取csv文件的库,很好用,读取出来之后,自己写入bean实体即可,依赖为compile 'de.siegmar:fastcsv:1.0.3'
https://github.com/osiegmar/FastCSV
143:获取图片上某个像素点的颜色值:
iv_image.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
if (event.getAction() == MotionEvent.ACTION_UP) {
int color = bitmap.getPixel(x, y);// 如果你想做的更细致的话 可以把颜色值的R G B 拿到做响应的处理
int r = Color.red(color);
int g = Color.green(color);
int b = Color.blue(color);
int a = Color.alpha(color);
Log.i(TAG, "r=" + r + ",g=" + g + ",b=" + b);
tv_rgb.setText("a=" + a + ",r=" + r + ",g=" + g + ",b="
+ b);
btnColor.setTextColor(Color.rgb(r, g, b));
}
return true;
}
});
https://blog.csdn.net/zhanggang740/article/details/50129297/
144:java中两个整数相除得到小数点并保留两位小数的方法(已记录)
https://blog.csdn.net/harryweasley/article/details/47658259
145:热力图
https://github.com/ChristianFF/HeatMapForAndroid
146:Android 设置图片 Bitmap任意透明度
https://blog.csdn.net/yanzi1225627/article/details/29661935
147:如果要动态添加一个view的时候,需要将view添加(addView)到父view之后,才能使用view的getLayoutParams方法,不然得到的就是null。
148:setPixel方法和setPixels方法需要在副本bitmap上面创建,getPixel方法和getPixels方法是得到图片上的像素点。
bitmap1=Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(), Bitmap.Config.ARGB_8888);
bitmap1.setPixels(ints, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
//////////////////////////////////////////////////
bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.icon);
int[] ints = new int[bitmap.getWidth() * bitmap.getHeight()];
bitmap.getPixels(ints, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
bitmap1 = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
for (int i = 0; i < bitmap1.getWidth(); i++) {
for (int j = 0; j < bitmap1.getHeight(); j++) {
int pixel = bitmap.getPixel(i, j);i和j可以当getPixel方法的参数获取到你想改变的那个像素点,但是ints[i*j]获取到的并不是实际你想的那个像素点。
int red = Color.red(pixel);
int green = Color.green(pixel);
int blue = Color.blue(pixel);
int alpha = Color.alpha(pixel);
// bitmap1.setPixel(i, j, ints[i*j]);
if (i % 5 == 0 && j % 5 == 0) {
bitmap1.setPixel(i, j, Color.argb(alpha, red, green, blue));
}
}
}
149:Java中小数和百分数的相互转化(已记录)
https://blog.csdn.net/qintian888/article/details/79538026
150:canvas的save方法和restore方法的使用,心得:save方法是保存之前canvas的状态(平移,旋转等),然后就可以在canvas上面画各种东西了,如果想恢复save之前的canvas的状态,只需要调用canvas的restore方法即可恢复,而不需要再进行各种反向操作,将canvas变回原来的状态,比较方便。
canvas.translate(100, 100);//画布必须先移动,再画,才能生效,如果是先画后移动,那么前 面画的是不受影响的,只有后面画的才会受到影响
canvas.drawARGB(255, 123, 111, 22);
canvas.drawText("hehe", 500, 200, paint);
canvas.drawBitmap(bitmap, 0, 0, paint);
canvas.rotate(90);
canvas.drawText("hehe", 90, 90, paint);
canvas.drawText("fde", 150, 150, paint);
canvas.rotate(-90);
canvas.drawText("和", 0, 0, paint);
以上代码等同于以下代码:
canvas.translate(100, 100);//画布必须先移动,再画,才能生效,如果是先画后移动,那么前 面画的是不受影响的,只有后面画的才会受到影响
canvas.drawARGB(255, 123, 111, 22);
canvas.drawText("hehe", 500, 200, paint);
canvas.drawBitmap(bitmap, 0, 0, paint);
canvas.save();
canvas.rotate(90);
canvas.drawText("hehe", 90, 90, paint);
canvas.drawText("fde", 150, 150, paint);
canvas.restore();
canvas.drawText("和", 0, 0, paint);
https://blog.csdn.net/oney139/article/details/8143281
151:可以将bitmap作为canvas的画布,然后在canvas中绘制各种图形,但是前提是bitmap必须是源bitmap的副本才行,因为android是不允许在代码里修改res文件里的图片的。
public static Bitmap drawRectForBitmap(Bitmap bitmap) {
Bitmap bitmap1 = bitmap.copy(bitmap.getConfig(), true);
Canvas canvas = new Canvas(bitmap1);
Paint p = new Paint();
p.setColor(Color.RED);
p.setTextSize(30);
canvas.drawText("花花", 100, 100, p);
return bitmap1;
}