Skip to content

Instantly share code, notes, and snippets.

@tondol
Created April 12, 2012 17:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tondol/2369304 to your computer and use it in GitHub Desktop.
Save tondol/2369304 to your computer and use it in GitHub Desktop.
LazyIconView
package jp.tondol.sample;
import java.net.HttpURLConnection;
import java.net.URL;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.StateListDrawable;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
public class LazyIconView extends ViewGroup {
protected ImageView backgroundImageView;
protected ImageView foregroundImageView;
protected View clickableView;
protected ProgressBarView progressBarView;
protected int iconSize = 80;
protected int thumbSize = 80;
protected int marginSize = 2;
protected final int DEFAULT_PROGRESS_BAR_SIZE = 40;
public LazyIconView(Context context) {
super(context);
initComponents();
}
public LazyIconView(Context context, AttributeSet attrs) {
super(context, attrs);
initComponents();
}
public void initComponents() {
removeAllViews();
backgroundImageView = new ImageView(getContext());
addView(backgroundImageView);
foregroundImageView = new ImageView(getContext());
addView(foregroundImageView);
progressBarView = new ProgressBarView(getContext());
progressBarView.setProgressBarSize(DEFAULT_PROGRESS_BAR_SIZE);
progressBarView.setBackgroundColor(Color.BLACK);
addView(progressBarView, new ViewGroup.LayoutParams(iconSize, iconSize));
clickableView = new View(getContext());
clickableView.setBackgroundDrawable(getStateList());
addView(clickableView);
updateLayout();
}
protected StateListDrawable getStateList() {
StateListDrawable stateList = new StateListDrawable();
stateList.addState(new int[] { android.R.attr.state_pressed },
new ColorDrawable(Color.GREEN));
stateList.addState(new int[] {},
new ColorDrawable(Color.TRANSPARENT));
return stateList;
}
public void updateLayout() {
double measuredScale = getMeasuredScale();
int m = (int) (marginSize * measuredScale);
int s = (int) (thumbSize * measuredScale);
backgroundImageView.layout(m, m, m + s, m + s);
foregroundImageView.layout(0, 0, s, s);
progressBarView.layout(0, 0, s, s);
clickableView.layout(0, 0, s, s);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
updateLayout();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// 自身のdimentionを決定する
setMeasuredDimension(getMeasuredSize(widthMeasureSpec),
getMeasuredSize(heightMeasureSpec));
// 子ビューのdimentionを決定する
int size = (int) (thumbSize * getMeasuredScale());
int spec = MeasureSpec.makeMeasureSpec(
size, MeasureSpec.EXACTLY);
backgroundImageView.measure(spec, spec);
foregroundImageView.measure(spec, spec);
progressBarView.measure(spec, spec);
clickableView.measure(spec, spec);
}
protected int getMeasuredSize(int measureSpec) {
int mode = MeasureSpec.getMode(measureSpec);
int size = MeasureSpec.getSize(measureSpec);
if (mode == MeasureSpec.EXACTLY) {
return size;
} else if (mode == MeasureSpec.AT_MOST) {
return Math.min(size, iconSize);
} else {
return iconSize;
}
}
protected double getMeasuredScale() {
return (double) iconSize / (double) (thumbSize + marginSize);
}
public void setIconSize(int size) {
iconSize = size;
}
public void setMarginSize(int size) {
marginSize = size;
}
public void setThumbSize(int size) {
thumbSize = size;
}
public void setProgressSize(int size) {
progressBarView.setProgressBarSize(size);
}
public ImageView getForegroundImageView() {
return foregroundImageView;
}
public ImageView getBackgroundImageView() {
return backgroundImageView;
}
public View getClickableImageView() {
return clickableView;
}
public void setForegroundImageUrl(String urlString) {
(new LoadAsyncTask(urlString)).execute();
}
// 画像を取得する非同期タスククラス
class LoadAsyncTask extends AsyncTask<Void, Void, Drawable> {
private String urlString;
public LoadAsyncTask(String urlString) {
this.urlString = urlString;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
progressBarView.setVisibility(View.VISIBLE);
}
@Override
protected void onPostExecute(Drawable result) {
super.onPostExecute(result);
if (result != null) {
foregroundImageView.setImageDrawable(result);
progressBarView.setVisibility(View.INVISIBLE);
}
}
@Override
protected Drawable doInBackground(Void... params) {
try {
URL resourceUrl = new URL(urlString);
HttpURLConnection conn =
(HttpURLConnection) resourceUrl.openConnection();
conn.setRequestMethod("GET");
return Drawable.createFromStream(conn.getInputStream(), null);
} catch (Exception e) {
android.util.Log.e("LazyIconView", e.toString());
return null;
}
}
}
static class ProgressBarView extends RelativeLayout {
protected ProgressBar progressBar;
protected int progressBarSize = 40;
public ProgressBarView(Context context) {
super(context);
initComponents();
}
public ProgressBarView(Context context, AttributeSet attrs) {
super(context, attrs);
initComponents();
}
public void initComponents() {
removeAllViews();
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
progressBarSize, progressBarSize);
lp.addRule(RelativeLayout.CENTER_IN_PARENT);
progressBar = new ProgressBar(getContext(), null,
android.R.attr.progressBarStyle);
progressBar.setLayoutParams(lp);
addView(progressBar);
}
public int getProgressBarSize() {
return progressBarSize;
}
public void setProgressBarSize(int size) {
progressBarSize = size;
initComponents();
}
}
}
package jp.tondol.sample;
import android.app.Activity;
import android.app.AlertDialog;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.LinearLayout;
public class SampleActivity extends Activity {
LazyIconView iconView;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
iconView = new LazyIconView(this);
Drawable d = getResources().getDrawable(R.drawable.icon_background);
iconView.setMarginSize(3); // 背景画像の影の幅
iconView.setThumbSize(120); // 背景画像の一辺の長さ
iconView.setIconSize(180); // 画面上に表示するときの大きさ
iconView.getBackgroundImageView().setImageDrawable(d); // 背景画像を設定
// アイコンに対してクリックリスナーを登録するときはこんな感じで
iconView.getClickableImageView().setClickable(true);
iconView.getClickableImageView().setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(SampleActivity.this);
builder.setTitle("sample");
builder.setMessage("onClick");
builder.show();
}
});
int FP = ViewGroup.LayoutParams.FILL_PARENT;
LinearLayout layout = new LinearLayout(this);
layout.setLayoutParams(new ViewGroup.LayoutParams(FP, FP));
layout.setBackgroundColor(Color.WHITE);
layout.addView(iconView);
setContentView(layout);
}
// レイアウトのサイズが確定したタイミングで呼ばれる
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
iconView.setForegroundImageUrl("http://tondol.com/static/image/icon.png"); // 読み込む画像を設定
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment