android 九宫格封装,Android 实现九宫格、点击图片放大全屏浏览等
live_icon.jpg
1370473-587d9058f76372fb.gif
说说我的实现思路:
逐渐掌握了Android开发套路,是时候自己去封装一些东西了。网上看了一些例子,感觉不是我想要的那种,我希望是直接导入就用,没有Activity,没有xml布局文件,全代码创建那种,使用者用起来直接用到一个类或者两个类就OK的那种。故此花了一点时间封装了这么一个九宫格:
需要有这么一个控件,这个控件是一个图片控件TScallImageView,点击这个图片会从图片位置开始放大至全屏TImageListBgView,点击后全屏缩小到原来位置,且放大缩小过程背景透明可以看见当前UI界面;这个全屏大部分人可能是start一个Activity(这样的话还得再功能清单文件添加该Activity,这不是我想要的),这里我直接添加到了window上;这些代码逻辑主要都写在TImageListBgView类中。
这里需要获取图片相对于window的位置:这里自定义了一个记录位置信息的类TRect
package com.tikeyc.tikeycandroid.custom.TNinePlaceGridView;
/**
* Created by public1 on 2017/5/23.
*/
public class TRect {
private int left;
private int top;
private int width;
private int height;
public TRect(int left, int top, int width, int height) {
this.left = left;
this.top = top;
this.width = width;
this.height = height;
}
public int getLeft() {
return left;
}
public int getTop() {
return top;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public void setLeft(int left) {
this.left = left;
}
public void setTop(int top) {
this.top = top;
}
public void setWidth(int width) {
this.width = width;
}
public void setHeight(int height) {
this.height = height;
}
@Override
public String toString() {
return "TRect{" +
"left=" + left +
", top=" + top +
", width=" + width +
", height=" + height +
'}';
}
}
图片控件:TScallImageView
该控件可以xml中创建也可代码创建,不过在调用其showImageToWindow()方法之前,需设置一下几个属性值:其中imageId及imageIds可以是图片URL也可以是图片id值。
public ViewGroup ninePlaceGridView;//外部设置
public Object imageId;//外部设置
public List imageIds;//外部设置
public int currentIndex;//外部设置
package com.tikeyc.tnineplacegridviewlibrary.TNinePlaceGridView;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;
/**
* Created by public1 on 2017/5/19.
*/
public class TScallImageView extends android.support.v7.widget.AppCompatImageView {
public static final int STATE_NORMAL = 0;
public static final int STATE_TRANSFORM_IN = 1;
public static final int STATE_TRANSFORM_OUT = 2;
public ViewGroup ninePlaceGridView;//外部设置
private TRect originalRect;//得到的第一个图片相对于window的位置
private List originalRects;//得到的第所有图片相对于window的位置
public Object imageId;//外部设置
public List imageIds;//外部设置
public int currentIndex;//外部设置
public TImageListBgView imageListBgView;
public TScallImageView(Context context) {
super(context);
init();
}
public TScallImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public TScallImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
showImageToWindow();
}
});
}
/**获取每个图片相对于window的位置
* @return
*/
private List getOriginalRects() {
List originalRects = new ArrayList();
int count = ninePlaceGridView.getChildCount();
for (int i = 0; i < count; i++) {
if (ninePlaceGridView.getChildAt(i) instanceof TScallImageView) {
TScallImageView scallImageView = (TScallImageView) ninePlaceGridView.getChildAt(i);
int[] outLocation = new int[2];
scallImageView.getLocationInWindow(outLocation);
Log.e("TAG","outLocation[0]:" + outLocation[0] + "outLocation[1]:" + outLocation[1]);
TRect tRect = new TRect(outLocation[0],outLocation[1],scallImageView.getWidth(),scallImageView.getHeight());
originalRects.add(tRect);
} else {
continue;
}
}
this.originalRects = originalRects;
return originalRects;
}
public void showImageToWindow() {
int[] outLocation = new int[2];
getLocationInWindow(outLocation);
// originalRect = new TRect(getLeft(),getTop(),getWidth(),getHeight());
// originalRect = new TRect(outLocation[0],outLocation[1] - TKCUtils.getStatusBarHeight(getContext()),getWidth(),getHeight());
originalRect = new TRect(outLocation[0],outLocation[1],getWidth(),getHeight());
imageListBgView = new TImageListBgView(getContext(),originalRect,this.imageId,this.imageIds,currentIndex);
imageListBgView.imageId = imageId;
imageListBgView.originalRects = getOriginalRects();
imageListBgView.startTransform(TScallImageView.STATE_TRANSFORM_IN);
}
}
TImageListBgView:图片放大缩小动画,横向滑动浏览等逻辑处理类
点击手机的返回按键,缩小图片:这里需要注意一点,在window上添加视图后点击手机的返回按键,不会响应当前的Activity,因此需要在添加在window上的视图TImageListBgView内重写public boolean dispatchKeyEvent(KeyEvent event)方法来实现:
/**因此View添加在Window,点击手机返回按钮无法响应,
* 重写此方法可以处理点击手机返回的逻辑处理,缩小图片到原位置
* @param event
* @return
*/
@Override
public boolean dispatchKeyEvent(KeyEvent event) {//2-4
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
if (mState == TScallImageView.STATE_TRANSFORM_IN) {
startTransform(TScallImageView.STATE_TRANSFORM_OUT);
return true;
}
}
return super.dispatchKeyEvent(event);
}
package com.tikeyc.tnineplacegridviewlibrary.TNinePlaceGridView;
import android.animation.Animator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import com.squareup.picasso.Picasso;
import java.util.List;
/**
* Created by public1 on 2017/5/23.
*/
public class TImageListBgView extends RelativeLayout {
public int mState = TScallImageView.STATE_NORMAL;
private TRect originalRect;
public List originalRects;
public Object imageId;
public List imageIds;
public int currentIndex;
private ImageView animationIV;
private LinearLayout gridViewBgView;
private GridView gridView;
private TPageHorizatalScrollView horizontalScrollView;
private TPageControl pageControl;
public TImageListBgView(Context context, TRect originalRect,Object imageId,List imageIds,int currentIndex) {
super(context);
this.originalRect = originalRect;
this.imageId = imageId;
this.imageIds = imageIds;
this.currentIndex = currentIndex;
setBackgroundColor(Color.TRANSPARENT);
initSubViews();
}
public TImageListBgView(Context context) {
super(context);
}
public TImageListBgView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TImageListBgView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
/**因此View添加在Window,点击手机返回按钮无法响应,
* 重写此方法可以处理点击手机返回的逻辑处理,缩小图片到原位置
* @param event
* @return
*/
@Override
public boolean dispatchKeyEvent(KeyEvent event) {//2-4
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
if (mState == TScallImageView.STATE_TRANSFORM_IN) {
startTransform(TScallImageView.STATE_TRANSFORM_OUT);
return true;
}
}
return super.dispatchKeyEvent(event);
}
@Override
public boolean dispatchKeyEventPreIme(KeyEvent event) {//1-3
return super.dispatchKeyEventPreIme(event);
}
private WindowManager windowManager;
private void initSubViews() {
//
initImageListBgView();
//
initAnimationIV();
//
initHorizontalScrollView();
//
initGridView();
//
initPageControl();
}
private void initImageListBgView() {
Activity activity = (Activity) getContext();
windowManager = activity.getWindowManager();
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
layoutParams.width = TRect.getScreenWidth(getContext());
layoutParams.height = TRect.getScreenHeight(getContext());
//FLAG_LAYOUT_IN_SCREEN
layoutParams.flags = WindowManager.LayoutParams.FLAG_FULLSCREEN;
layoutParams.format = PixelFormat.RGBA_8888;//让背景透明,放大过程可以看到当前界面
layoutParams.verticalMargin = 0;
windowManager.addView(this,layoutParams);
}
private void initAnimationIV() {
animationIV = new ImageView(getContext());
// imageView.setBackgroundColor(Color.RED);
animationIV.setScaleType(ImageView.ScaleType.FIT_CENTER);
LayoutParams params = new LayoutParams(originalRect.getWidth(),originalRect.getHeight());
params.leftMargin = originalRect.getLeft();
params.topMargin = originalRect.getTop();
addView(animationIV,params);
// Picasso.with(getContext()).load("http://ww2.sinaimg.cn/mw690/9e6995c9gw1f2uu70bzohj209q06g3yw.jpg").into(animationIV);
if (imageId instanceof Integer) {
animationIV.setImageResource((Integer) imageId);
} else {
Picasso.with(getContext()).load((String) imageId).into(animationIV);
}
}
private void initHorizontalScrollView() {
horizontalScrollView = new TPageHorizatalScrollView(getContext());
LayoutParams hsLayoutParams = new LayoutParams(TRect.getScreenWidth(getContext()),TRect.getScreenHeight(getContext()));
hsLayoutParams.leftMargin = 0;
hsLayoutParams.topMargin = 0;
addView(horizontalScrollView,hsLayoutParams);
horizontalScrollView.mBaseScrollX = currentIndex*TRect.getScreenWidth(getContext());
horizontalScrollView.setOnScrollToIndexListen(new TPageHorizatalScrollView.OnScrollToIndexListen() {
@Override
public void scrollToIndex(int index) {
currentIndex = index;
if (currentIndex >= imageIds.size()){
currentIndex = imageIds.size() - 1;
} else if (currentIndex < 0) {
currentIndex = 0;
}
Log.e("TAG","currentIndex" + currentIndex);
if (imageId instanceof Integer) {
animationIV.setImageResource((Integer) imageIds.get(currentIndex));
} else {
Picasso.with(getContext()).load((String) imageIds.get(currentIndex)).into(animationIV);
}
originalRect = originalRects.get(currentIndex);
pageControl.setCurrentPage(currentIndex);
}
});
int numColumns = imageIds.size();
gridViewBgView = new LinearLayout(getContext());
LinearLayout.LayoutParams testParams = new LinearLayout.LayoutParams(TRect.getScreenWidth(getContext())*numColumns,TRect.getScreenHeight(getContext()));
horizontalScrollView.addView(gridViewBgView,testParams);
}
private void initGridView() {
int numColumns = imageIds.size();
//
gridView = new GridView(getContext());
gridView.setNumColumns(numColumns);
gridView.setColumnWidth(TRect.getScreenWidth(getContext()));
LinearLayout.LayoutParams gridViewLayoutParams = new LinearLayout.LayoutParams(TRect.getScreenWidth(getContext())*numColumns,TRect.getScreenHeight(getContext()));
gridViewLayoutParams.leftMargin = 0;
gridViewLayoutParams.topMargin = 0;
gridViewBgView.addView(gridView,gridViewLayoutParams);
final TImageGridViewAdapter adapter = new TImageGridViewAdapter(getContext());
adapter.imageIds = this.imageIds;
gridView.setAdapter(adapter);
adapter.setOnItemClickListener(new TImageGridViewAdapter.OnItemClickListener() {
@Override
public void onItemClick(int i, View view) {
startTransform(TScallImageView.STATE_TRANSFORM_OUT);
}
});
// gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
// @Override
// public void onItemClick(AdapterView> adapterView, View view, int i, long l) {
// startTransform(TScallImageView.STATE_TRANSFORM_OUT);
// }
// });
}
private void initPageControl() {
pageControl = new TPageControl(getContext(),null);
pageControl.setPageNumber(imageIds.size());
pageControl.setSelectedColor(Color.RED);
LayoutParams layoutParams = new LayoutParams(TRect.getScreenWidth(getContext()),40);
layoutParams.topMargin = TRect.getScreenHeight(getContext()) - 100;
addView(pageControl,layoutParams);
}
/**放大缩小动画
* @param state
*/
public void startTransform(final int state) {
final int duration = 300;
ValueAnimator valueAnimator = new ValueAnimator();
valueAnimator.setDuration(duration);
valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
if (state == TScallImageView.STATE_TRANSFORM_IN) {
setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
mState = TScallImageView.STATE_TRANSFORM_IN;
gridViewBgView.setVisibility(INVISIBLE);
pageControl.setVisibility(INVISIBLE);
// PropertyValuesHolder scaleHolder = PropertyValuesHolder.ofFloat("scale", mTransfrom.startScale, mTransfrom.endScale);
PropertyValuesHolder leftHolder = PropertyValuesHolder.ofFloat("left",originalRect.getLeft(), 0);
PropertyValuesHolder topHolder = PropertyValuesHolder.ofFloat("top", originalRect.getTop(), 0);
PropertyValuesHolder widthHolder = PropertyValuesHolder.ofFloat("width", originalRect.getWidth(), TRect.getScreenWidth(getContext()));
PropertyValuesHolder heightHolder = PropertyValuesHolder.ofFloat("height", originalRect.getHeight(), TRect.getScreenHeight(getContext()));
PropertyValuesHolder alphaHolder = PropertyValuesHolder.ofInt("alpha", 0, 255);
valueAnimator.setValues(leftHolder, topHolder, widthHolder, heightHolder, alphaHolder);
} else {
// setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN);
gridViewBgView.setVisibility(INVISIBLE);
pageControl.setVisibility(INVISIBLE);
animationIV.setVisibility(VISIBLE);
setBackgroundColor(Color.TRANSPARENT);
mState = TScallImageView.STATE_TRANSFORM_OUT;
// PropertyValuesHolder scaleHolder = PropertyValuesHolder.ofFloat("scale", mTransfrom.endScale, mTransfrom.startScale);
PropertyValuesHolder leftHolder = PropertyValuesHolder.ofFloat("left", animationIV.getLeft(), originalRect.getLeft());
PropertyValuesHolder topHolder = PropertyValuesHolder.ofFloat("top", animationIV.getTop(), originalRect.getTop());
PropertyValuesHolder widthHolder = PropertyValuesHolder.ofFloat("width", animationIV.getWidth(), originalRect.getWidth());
PropertyValuesHolder heightHolder = PropertyValuesHolder.ofFloat("height", animationIV.getHeight(), originalRect.getHeight());
PropertyValuesHolder alphaHolder = PropertyValuesHolder.ofInt("alpha", 255, 0);
valueAnimator.setValues(leftHolder, topHolder, widthHolder, heightHolder, alphaHolder);
// Handler handler = new Handler(){
// @Override
// public void handleMessage(Message msg) {
// super.handleMessage(msg);
// animationIV.setScaleType(ImageView.ScaleType.CENTER_CROP);//根据九宫格中的图片的显示模式设置
// }
// };
// handler.sendEmptyMessageDelayed(0,duration*9/10);
}
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public synchronized void onAnimationUpdate(ValueAnimator animation) {
// mTransfrom.scale = (Float) animation.getAnimatedValue("scale");
Float left = (Float) animation.getAnimatedValue("left");
Float top = (Float) animation.getAnimatedValue("top");
Float width = (Float) animation.getAnimatedValue("width");
Float height = (Float) animation.getAnimatedValue("height");
Integer mBgAlpha = (Integer) animation.getAnimatedValue("alpha");
LayoutParams layoutParams = new LayoutParams(width.intValue(),height.intValue());
layoutParams.leftMargin = left.intValue();
layoutParams.topMargin = top.intValue();
animationIV.setLayoutParams(layoutParams);
setAlpha(mBgAlpha);
}
});
final TImageListBgView[] imageListBgView = {this};
valueAnimator.addListener(new ValueAnimator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
/*
* 如果是进入的话,当然是希望最后停留在center_crop的区域。但是如果是out的话,就不应该是center_crop的位置了
* , 而应该是最后变化的位置,因为当out的时候结束时,不回复视图是Normal,要不然会有一个突然闪动回去的bug
*/
// TODO 这个可以根据实际需求来修改
if (mState == TScallImageView.STATE_TRANSFORM_IN) {
horizontalScrollView.baseSmoothScrollTo(0);
setBackgroundColor(Color.BLACK);
pageControl.setVisibility(VISIBLE);
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
gridViewBgView.setVisibility(VISIBLE);
animationIV.setVisibility(INVISIBLE);
}
};
handler.sendEmptyMessageDelayed(0, duration);
} else if (mState == TScallImageView.STATE_TRANSFORM_OUT) {
gridViewBgView.removeView(gridView);
gridView = null;
horizontalScrollView.removeView(gridViewBgView);
gridViewBgView = null;
removeView(animationIV);
animationIV = null;
removeView(pageControl);
pageControl = null;
windowManager.removeView(imageListBgView[0]);
imageListBgView[0] = null;
}
}
@Override
public void onAnimationCancel(Animator animation) {
}
});
valueAnimator.start();
}
}
如何使用,非常之简单
- List> imageNames2D = new ArrayList>();
List imageNames = new ArrayList();
imageNames2D.add(imageNames);
imageNames.add(Object);
- TNinePlaceGridView ninePlaceGridView = (TNinePlaceGridView) view.findViewById(R.id.ninePlaceGridView);
- ninePlaceGridView.setImageNames(imageNames);
如下代码示例:
public class MainActivity extends AppCompatActivity {
@ViewInject(R.id.listView)
private ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
x.view().inject(this);
init();
}
private void init() {
List> imageNames2D = new ArrayList>();
for (int i = 0; i < 30; i++) {
ArrayList imageNames = new ArrayList();
Random random = new Random();
for (int j = 0; j <= random.nextInt(8); j++) {
if (j%2 == 0) {
imageNames.add(R.mipmap.beauty);
// imageNames.add("http://7xi8d6.com1.z0.glb.clouddn.com/20171011084856_0YQ0jN_joanne_722_11_10_2017_8_39_5_505.jpeg");
} else {
imageNames.add(R.mipmap.glenceluanch);
// imageNames.add("http://7xi8d6.com1.z0.glb.clouddn.com/2017-10-10-sakura.gun_10_10_2017_12_33_34_751.jpg");
}
}
imageNames2D.add(imageNames);
}
ListViewAdapter listViewAdapter = new ListViewAdapter(this);
listViewAdapter.imageNames2D = imageNames2D;
listView.setAdapter(listViewAdapter);
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
}
private class ListViewAdapter extends BaseAdapter {
private Context context;
public List> imageNames2D;
public ListViewAdapter(Context context) {
this.context = context;
}
@Override
public int getCount() {
if (imageNames2D != null) return imageNames2D.size();
return 0;
}
@Override
public Object getItem(int i) {
return null;
}
@Override
public long getItemId(int i) {
return 0;
}
private class ViewHelper {
CircleImageView imageViewIcon;
TextView textViewNickName;
TNinePlaceGridView ninePlaceGridView;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHelper viewHelper;
if (view == null) {
view = View.inflate(context,R.layout.timage_listactivity_listview_item,null);
viewHelper = new ViewHelper();
viewHelper.imageViewIcon = (CircleImageView) view.findViewById(R.id.imageViewIcon);
viewHelper.textViewNickName = (TextView) view.findViewById(R.id.textViewNickName);
viewHelper.ninePlaceGridView = (TNinePlaceGridView) view.findViewById(R.id.ninePlaceGridView);
view.setTag(viewHelper);
} else {
viewHelper = (ViewHelper) view.getTag();
}
List imageNames = this.imageNames2D.get(i);
viewHelper.ninePlaceGridView.setImageNames(imageNames);
return view;
}
}
}
android 九宫格封装,Android 实现九宫格、点击图片放大全屏浏览等相关推荐
- Android 实现九宫格、点击图片放大全屏浏览等
项目GitHub地址https://github.com/tikeyc/TNinePlaceGridView_Android https://github.com/tikeyc/TikeycAndro ...
- 点击图片放大全屏加载,再次点击图片/文档回到原来位置
导读:生命不息,折腾不止 第二次写文章,其实我一直都不明白为什么很多人喜欢写文章,现在我好想知道一点点了,学到的东西一旦过了一段时间,好像就忘了- 看来写文章,或许有这么个原因吧,担心有一天忘了. 回 ...
- Android 点击图片放大至全屏 再次点击关闭过度动画 Shared Element效果(共享元素效果)
Android 点击图片放大至全屏 再次点击关闭过度动画 最近项目需要给用户一个体验优化,各种查阅,然后改了很多地方,类似于图片的点击预览,消息列表的点击流畅过渡. Shared Element效果( ...
- 仿微信点击图片放大,并可滑动浏览效果
前言 我们在微信朋友圈看别人发的带图片说说时,点击某张图片,会放大全屏显示,并且左右滑动可以切换浏览多张图片. 这种效果应用场景很多,尤其是购物和餐饮类app很常见.比如点餐软件,一般会向顾客 ...
- 原生js实现点击按钮切换全屏!
使用fullScreen API实现全屏 <head><meta charset="UTF-8"><meta name="viewport& ...
- vue项目 一行js代码搞定点击图片放大缩小
一行js代码搞定xue项目需要点击图片放大缩小,其实主要用的是用到了vue:class的动态切换,内容比较简单.一开始我把维护的需求想得太复杂了,和测试小姐姐聊了一下才反应过来. 两个月不到跟了四个项 ...
- 点击图片放大至原始图片大小
有些时候为了排版的整洁,页面展示的图片不得不都是限定宽高的,如果想要点击图片放大至原始大小进行预览,再次点击回到原来样子,就要用到下面的代码了: var _w = parseInt($(window) ...
- 点击图片放大缩小功能
1.点击图片放大缩小的思路 图片部分: <table><div><img style="width:62px;height:83px;display:block ...
- jquery点击图片放大效果
点击图片放大效果无非就是创建一个大容器,点击小图片获取图片路径存放到大容器里. 接下来看一下效果图 HTML结构 <img class="enlargeImg" width= ...
最新文章
- RDS读写分离,海量数据一键搞定
- c 结构体 不允许使用不完整的类型_C语言必学知识点 quot;结构体quot;详细解析!...
- linux redis 删除_Redis-安装amp;删除【Linux 版】
- 【转】ubuntu 11.10(32位系统)下编译android源码
- 工程师必备:C/C 单元测试万能插桩工具
- [leetcode] N-Queens II
- 为普及再助一把力!《2021年中国低代码/无代码市场研究报告》正式发布
- spd不能修改服务器内存条的原因,修改内存SPD 解决蓝屏问题
- 计算机ps一级知识点,2017年计算机等级一级Photoshop常考知识点
- linux宝塔面板下安装mindoc参考
- python评分卡3_woe与IV分箱实现
- win10安装串口驱动pl2303 ch340 cp2102时安装不上的一些解决办法
- 赵小楼《天道》《遥远的救世主》深度解析(114)时刻要认清自己的本位
- ffmpeg实战教程(十一)手把手教你实现直播功能,不依赖第三方SDK
- 51信用卡 Android 架构演进实践
- spring boot注解@PostConstruct
- MFC颜色调配 | vc++6.0颜色设置,如何修改控件颜色
- 虚拟机ubuntu系统鼠标移动消失
- lookup与VLOOKUP对比使用;sumifs与sumproduct对比使用(Excel 100例)
- JavaScript菜鸟教程 grammar
热门文章
- 原生js春节倒计时@酷酷航
- android studio signingconfigs 打正式包,Android-SigningConfigs打包配置
- Android requires compiler compliance level 5.0 or 6.0. Found '1.7' instead.
- 纵即逝的烟花蓄势于纸
- 淘宝美工设计就业怎么样?零基础学淘宝美工设计怎么学?
- MySQL数据库的存储引擎
- python导入库关键词_怎么样导入RobotFramework 自定义关键字(库文件)
- Avril Lavigne: Complicated
- 个性和共性,对共性的封装。新的语言是如何诞生的
- c++获取系统时间实例2