为什么qq牧场打不开幸运九宫格打不开

当前位置: >
今日最新文章
今日最新软件
热门文章排行章
热门软件排行Android:NineGridLayout — 仿微信朋友圈和QQ空间的九宫格图片展示自定义控件
日期: 18:05:20
来源:ITeye
Android:NineGridLayout — 仿微信朋友圈和QQ空间的九宫格图片展示自定义控件
NineGridLayout
一个仿微信朋友圈和QQ空间的九宫格图片展示自定义控件。
1、当只有1张图时,可以自己定制图片宽高,也可以使用默认九宫格的宽高;
2、当只有4张图时,以2*2的方式显示;
3、除以上两种情况下,都是按照3列方式显示,但这时有一些细节:
a、如果只有9张图,当然是以3*3的方式显示;
b、如果超过9张图,可以设置是否全部显示。
如果设置不完全显示,则按照3*3的方式显示,但是在第9张图上会有一个带“+”号的数字,
代表还有几张没有显示,这里是模仿了QQ空间图片超出9张的显示方式;
如果设置全部显示,理所当然的将所有图片都显示出来。
4、图片被按下时,会有一个变暗的效果,这也是模仿微信朋友圈的效果。
二、使用方法
1、核心类是NineGridLayout,继承自ViewGroup的抽象类,所以我们实际项目使用需要继承它,并要实现3个方法,如下:
public abstract class NineGridLayout extends ViewGroup {
//******************************其他代码省略**************************
* 显示一张图片
* @param imageView
* @param url
* @param parentWidth 父控件宽度
* @return true 代表按照九宫格默认大小显示,false 代表按照自定义宽高显示
protected abstract boolean displayOneImage(RatioImageView imageView, String url, int parentWidth);
protected abstract void displayImage(RatioImageView imageView, String url);
* 点击图片时执行
protected abstract void onClickImage(int position, String url, List&String& urlList);
2、我这里用NineGridTestLayout继承NineGridLayout实现,displayOneImage()与displayImage()中的参数都是显示图片需要的,我这里用的是ImageLoader显示图片,当然你也可以用其他的。
public class NineGridTestLayout extends NineGridLayout {
protected static final int MAX_W_H_RATIO = 3;
public NineGridTestLayout(Context context) {
super(context);
public NineGridTestLayout(Context context, AttributeSet attrs) {
super(context, attrs);
protected boolean displayOneImage(final RatioImageView imageView, String url, final int parentWidth) {
//这里是只显示一张图片的情况,显示图片的宽高可以根据实际图片大小自由定制,parentWidth 为该layout的宽度
ImageLoader.getInstance().displayImage(imageView, url, ImageLoaderUtil.getPhotoImageOption(), new ImageLoadingListener() {
public void onLoadingStarted(String imageUri, View view) {
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
public void onLoadingComplete(String imageUri, View view, Bitmap bitmap) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
if (h & w * MAX_W_H_RATIO) {//h:w = 5:3
newW = parentWidth / 2;
newH = newW * 5 / 3;
} else if (h & w) {//h:w = 2:3
newW = parentWidth * 2 / 3;
newH = newW * 2 / 3;
} else {//newH:h = newW :w
newW = parentWidth / 2;
newH = h * newW /
setOneImageLayoutParams(imageView, newW, newH);
public void onLoadingCancelled(String imageUri, View view) {
// true 代表按照九宫格默认大小显示(此时不要调用setOneImageLayoutParams);false 代表按照自定义宽高显示。
protected void displayImage(RatioImageView imageView, String url) {
ImageLoaderUtil.getImageLoader(mContext).displayImage(url, imageView, ImageLoaderUtil.getPhotoImageOption());
protected void onClickImage(int i, String url, List&String& urlList) {
Toast.makeText(mContext, "点击了图片" + url, Toast.LENGTH_SHORT).show();
3、在xml中实现
&com.hmy.ninegridlayout.view.NineGridTestLayout xmlns:app="/apk/res-auto"
android:id="@+id/layout_nine_grid"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:sapcing="4dp" /&
app:sapcing是设置九宫格中图片之间的间隔。
public List&String& urlList = new ArrayList&&();//图片url
NineGridTestLayout layout = (NineGridTestLayout) view.findViewById(R.id.layout_nine_grid);
layout.setIsShowAll(false); //当传入的图片数超过9张时,是否全部显示
layout.setSpacing(5); //动态设置图片之间的间隔
holder.layout.setUrlList(urlList); //最后再设置图片url
三、核心类
NineGridLayout.java
* 作者:HMY
public abstract class NineGridLayout extends ViewGroup {
private static final float DEFUALT_SPACING = 3f;
private static final int MAX_COUNT = 9;
protected Context mC
private float mSpacing = DEFUALT_SPACING;
private int mC
private int mR
private int mTotalW
private int mSingleW
private boolean mIsShowAll =
private boolean mIsFirst =
private List&String& mUrlList = new ArrayList&&();
public NineGridLayout(Context context) {
super(context);
init(context);
public NineGridLayout(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.NineGridLayout);
mSpacing = typedArray.getDimension(R.styleable.NineGridLayout_sapcing, DEFUALT_SPACING);
typedArray.recycle();
init(context);
private void init(Context context) {
mContext =
if (getListSize(mUrlList) == 0) {
setVisibility(GONE);
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
mTotalWidth = right -
mSingleWidth = (int) ((mTotalWidth - mSpacing * (3 - 1)) / 3);
if (mIsFirst) {
notifyDataSetChanged();
mIsFirst =
* 设置间隔
* @param spacing
public void setSpacing(float spacing) {
mSpacing =
* 设置是否显示所有图片(超过最大数时)
* @param isShowAll
public void setIsShowAll(boolean isShowAll) {
mIsShowAll = isShowA
public void setUrlList(List&String& urlList) {
if (getListSize(urlList) == 0) {
setVisibility(GONE);
setVisibility(VISIBLE);
mUrlList.clear();
mUrlList.addAll(urlList);
if (!mIsFirst) {
notifyDataSetChanged();
public void notifyDataSetChanged() {
removeAllViews();
int size = getListSize(mUrlList);
if (size & 0) {
setVisibility(VISIBLE);
setVisibility(GONE);
if (size == 1) {
String url = mUrlList.get(0);
RatioImageView imageView = createImageView(0, url);
//避免在ListView中一张图未加载成功时,布局高度受其他item影响
LayoutParams params = getLayoutParams();
params.height = mSingleW
setLayoutParams(params);
imageView.layout(0, 0, mSingleWidth, mSingleWidth);
boolean isShowDefualt = displayOneImage(imageView, url, mTotalWidth);
if (isShowDefualt) {
layoutImageView(imageView, 0, url, false);
addView(imageView);
generateChildrenLayout(size);
layoutParams();
for (int i = 0; i & i++) {
String url = mUrlList.get(i);
RatioImageView imageV
if (!mIsShowAll) {
if (i & MAX_COUNT - 1) {
imageView = createImageView(i, url);
layoutImageView(imageView, i, url, false);
} else { //第9张时
if (size &= MAX_COUNT) {//刚好第9张
imageView = createImageView(i, url);
layoutImageView(imageView, i, url, false);
} else {//超过9张
imageView = createImageView(i, url);
layoutImageView(imageView, i, url, true);
imageView = createImageView(i, url);
layoutImageView(imageView, i, url, false);
private void layoutParams() {
int singleHeight = mSingleW
//根据子view数量确定高度
LayoutParams params = getLayoutParams();
params.height = (int) (singleHeight * mRows + mSpacing * (mRows - 1));
setLayoutParams(params);
private RatioImageView createImageView(final int i, final String url) {
RatioImageView imageView = new RatioImageView(mContext);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
onClickImage(i, url, mUrlList);
return imageV
* @param imageView
* @param url
* @param showNumFlag 是否在最大值的图片上显示还有未显示的图片张数
private void layoutImageView(RatioImageView imageView, int i, String url, boolean showNumFlag) {
final int singleWidth = (int) ((mTotalWidth - mSpacing * (3 - 1)) / 3);
int singleHeight = singleW
int[] position = findPosition(i);
int left = (int) ((singleWidth + mSpacing) * position[1]);
int top = (int) ((singleHeight + mSpacing) * position[0]);
int right = left + singleW
int bottom = top + singleH
imageView.layout(left, top, right, bottom);
addView(imageView);
if (showNumFlag) {//添加超过最大显示数量的文本
int overCount = getListSize(mUrlList) - MAX_COUNT;
if (overCount & 0) {
float textSize = 30;
final TextView textView = new TextView(mContext);
textView.setText("+" + String.valueOf(overCount));
textView.setTextColor(Color.WHITE);
textView.setPadding(0, singleHeight / 2 - getFontHeight(textSize), 0, 0);
textView.setTextSize(textSize);
textView.setGravity(Gravity.CENTER);
textView.setBackgroundColor(Color.BLACK);
textView.getBackground().setAlpha(120);
textView.layout(left, top, right, bottom);
addView(textView);
displayImage(imageView, url);
private int[] findPosition(int childNum) {
int[] position = new int[2];
for (int i = 0; i & mR i++) {
for (int j = 0; j & mC j++) {
if ((i * mColumns + j) == childNum) {
position[0] =//行
position[1] =//列
* 根据图片个数确定行列数量
* @param length
private void generateChildrenLayout(int length) {
if (length &= 3) {
mRows = 1;
mColumns =
} else if (length &= 6) {
mRows = 2;
mColumns = 3;
if (length == 4) {
mColumns = 2;
mColumns = 3;
if (mIsShowAll) {
mRows = length / 3;
int b = length % 3;
if (b & 0) {
mRows = 3;
protected void setOneImageLayoutParams(RatioImageView imageView, int width, int height) {
imageView.setLayoutParams(new LayoutParams(width, height));
imageView.layout(0, 0, width, height);
LayoutParams params = getLayoutParams();
params.width =
params.height =
setLayoutParams(params);
private int getListSize(List&String& list) {
if (list == null || list.size() == 0) {
return list.size();
private int getFontHeight(float fontSize) {
Paint paint = new Paint();
paint.setTextSize(fontSize);
Paint.FontMetrics fm = paint.getFontMetrics();
return (int) Math.ceil(fm.descent - fm.ascent);
* @param imageView
* @param url
* @param parentWidth 父控件宽度
* @return true 代表按照九宫格默认大小显示,false 代表按照自定义宽高显示
protected abstract boolean displayOneImage(RatioImageView imageView, String url, int parentWidth);
protected abstract void displayImage(RatioImageView imageView, String url);
protected abstract void onClickImage(int position, String url, List&String& urlList);
RatioImageView.java
该类有两个功能:
1、是用于ImageView被按下时有变暗效果
2、ImageView的宽高根据设置的比例动态适配高度,如在xml中设置
app:ratio="2" ,ImageView的高度根据其宽度改变,但始终是宽的2倍,该功能在该项目中没有使用。
* 根据宽高比例自动计算高度ImageView
* Created by HMY on .
public class RatioImageView extends ImageView {
* 宽高比例
private float mRatio = 0f;
public RatioImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
public RatioImageView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RatioImageView);
mRatio = typedArray.getFloat(R.styleable.RatioImageView_ratio, 0f);
typedArray.recycle();
public RatioImageView(Context context) {
super(context);
* 设置ImageView的宽高比
* @param ratio
public void setRatio(float ratio) {
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
if (mRatio != 0) {
float height = width / mR
heightMeasureSpec = MeasureSpec.makeMeasureSpec((int) height, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Drawable drawable = getDrawable();
if (drawable != null) {
drawable.mutate().setColorFilter(Color.GRAY,
PorterDuff.Mode.MULTIPLY);
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
Drawable drawableUp = getDrawable();
if (drawableUp != null) {
drawableUp.mutate().clearColorFilter();
return super.onTouchEvent(event);
代码可在我的GitHub上下载,地址:
本页内容版权归属为原作者,如有侵犯您的权益,请通知我们删除。
扫描本地文件加载到item 不限于应用到音乐播放器,其他Android工程,也可以使用SdcardSearchToList 其他Android工程也可以使用,我现在做了很小的Demo 后续将博文,将在播放器里,加入这一功能,来实现刚下载好的音乐,加载到播放器 这个Demo的源码下载: http://download.csdn.net/album/detail/3105 名称为:SdcardSearchToList,如果没有显示,可能还没有审核完成 不下载也可以,因为只有1个java文件,2个xml文件,非常
ListView作为android中最常使用的控件,可以以条目的形式显示大量的数据,经常被用于显示最近联系人列表,对于每一个 Item,均要求adapter的getView方法返回一个View,因此ListView的实现是离不开Adapter的,如果以MVC的思想来看ListView的话,ListView的显示相当于V,Adapter部分相当于C,而数据部分就相当于M了,接下来的几篇博客计划对ListView自己所了解的一些优化措施总结一下,希望能够帮助到大家;
先来看看如
前面的几篇文章都是讲解的android中的窗口显示机制,包括Activity窗口加载绘制流程,Dialog窗口加载绘制流程,PopupWindow窗口加载绘制流程,Toast窗口加载绘制流程等等。整个Android的界面显示的原理都是类似的,都是通过Window对象控制View组件,实现加载与绘制流程。 这篇文章休息一下,不在讲解Android的窗口绘制机制,穿插的讲解一下Android系统的异常处理流程。O(∩_∩)O哈哈~ 开发过android项目的童鞋对android系统中错误弹窗,force cl
首先说一下canvas类: Class OverviewThe Canvas class holds the "draw" calls. To draw something, you need 4 basic components: A Bitmap to hold the pixels, a Canvas to host the draw calls (writing into the bitmap), a drawing primitive (e.g. Rect, Path, text , Bitma
android 性能优化 java 代码优化 主要优化java 代码 对象, (等待kotlin) jvm 内存分三块,常量区(静态代码,指向的),堆,栈,static 变量的利用 ,一些全局变量的引用 如? 如 : context 拿了 activuty 的引用 context 使用不当 a=b; // 相当于 a 保留 b 的引用 b=a; a.finisg(); b.finish(); // 会造成内存泄露 ,ab 都不能回收 ,因为回收a 时 , b 还在引用它 ,则都不能回收 便会造成内存泄露
经常在 Xcode IDE 里面的代码中看到以下代码指令: #pragma mark - #pragma mark Initialization #pragma 是什么 从技术上讲,以 #pragma 开头的代码是一条编译器指令,是一个特定于程序或编译器的指令。它们不一定适用于其它编译器或其它环境。如果编译器不能识别该指令,则会将其忽略。 作用 它们告诉Xcode编译器,要在编辑器窗格顶部的方法和函数弹出菜单中将代码分隔开,如下图所示: 一些类(尤其是一些控制器类)可能很长,方法和函数弹出菜单可以便于代码
Android的多媒体框架包括支持播放多种常见的媒体类型,使您可以轻松地把音频、视频和图像集成到你的应用。你可以播放音频或视频媒体文件,这些文件是存储在你的应用程序的资源文件中的。应用程序的资源文件可以是文件系统中独立的文件,或通过网络连接获取的一个数据流,所有使用MediaPlayer APIS的资源文件。 1.注意: 如果你通过一个URL来获取一个在线媒体文件,该文件必须能够支持渐进式下载。 2.警告: 当你使用setDataSource()方法时,必须捕捉或通过非法数据异常和输入输出异常,因为正在被
Mecanim动画系统
Mecanim Animation System Date: 07:48 Unity has a rich and sophisticated animation system called
Mecanim . Mecanim provides: Unity有一个丰富并且精密的动画系统叫做 Mecanim 。Mecanim提供了: Easy workflow and setup of animations on humanoid characters.
如果你想要保持CPU的运行以至于可以在设备休眠之前完成一些工作,你可以使用PowerManager调用wake locks. wake locks允许你的应用控制power state。
创建和保持唤醒锁可以对设备的电池寿命产生巨大影响。因此你应该在极其需要它的地方使用,并尽可能的短时间的使用它。例如,你绝不需要在activity中使用wake lock 。同上所属,如果你想保持屏幕长亮,请使用FLAG_KEEP_SCREEN_ON。
一个合理的使用案例,使用唤醒锁的可能是bac
前言 在Android中使用 MVP 来开发已经出来很久了,刚好Google又出了一系列的architecture samples,在此就整理一下对于MVP的认知和实践总结,这篇文章会随着使用经验的丰富而不断更新。 1. 介绍MVC 在没有使用MVP开发之前,我们一直使用的都是MVC模式,其实也不算的MVC,一般我们听到的都是Android中的Activity既是View,又是Controller,即Activity既负责View的显示,又负责处理业务逻辑,这是我们一般听到的,但其实我们的Activity
Copyright (C)
ITfish.net求QQ空间相册九宫格首页图片 摩天轮
全部答案(共1个回答)
手机上传,首先,应该进入自己的空间,然后点击进入主页,点击主页下面的相册,再就点击上传照片,进去自己手机的相册,点击你想上传的照片,再确定上传,就把照片传到了空...
设置-辅助功能-打开QQ输入法
用软件市场搜或用浏览器搜,只要格式正确就可以下载用了
游乐园中的摩天轮,能看到最远最高的地方.听说,摩天轮里的每个格子都装满了幸福,眺望摩天轮的人,其实也在眺望幸福.那么守望摩天轮的人,就是守望幸福的守望者。因为摩...
答: 手机能无线免费上网吗?
答: 买路由肯定可以,拿一根网线建个局域网也应该可以
答: 门户网站门户(portal)。原意是指正门、入口,现多用于互联网的门户网站和企业应用系统的门户系统。广义注解这里是一个应用框架,它将各种应用系统、数据资源和互联...
大家还关注
确定举报此问题
举报原因(必选):
广告或垃圾信息
激进时政或意识形态话题
不雅词句或人身攻击
侵犯他人隐私
其它违法和不良信息
报告,这不是个问题
报告原因(必选):
这不是个问题
这个问题分类似乎错了
这个不是我熟悉的地区
相关问答:123456789101112131415

我要回帖

更多关于 为什么qq牧场打不开 的文章

 

随机推荐