今日林北心血來潮要來寫一個簡單的相簿軟體,功能包括

1. 小圖預覽

2. 大圖檢視

Screenshot_2015-06-02-11-29-31  

 

利用 HorizontalScrollView 實現小圖預覽

很久以前記得有個 Gallery 的元件可以用,但 Android 4.1 之後好像不再支援了,改用 HorizontalScrollView  這個元件

Class Overview: http://developer.android.com/reference/android/widget/HorizontalScrollView.html

HorizontalScrollView 是一個 view containter,讓 user 可以用滑動方式存取到肉眼看得到的更多元件,至少要放一個 child 到 HorizontalScrollView 中,通常為 LinearLayout,並自行管理內部的原件。

本文中在 HorizontalScrollView 中實作一個客製化的 LinearLayout,利用 Adapter 與 ImageSwitcher 進行互動。

 

利用 ImageSwitcher 實現大圖檢視

ImageSwitcher 是一個有動畫效果的圖片切換器

Class Overview: https://developer.android.com/reference/android/widget/ImageSwitcher.html

實作 ImageSwitcher 時,Activity 必須繼承 ViewFactory,並 override makeView() 方法,通過其創建 View,再將 View 添加到 ImageSwitcher 上

 

實作方式如下

 

首先在 main.xml 中宣告 HorizontalScrollView & ImageSwitcher :

<HorizontalScrollView android:id="@+id/hsview"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_weight="0"
android:scrollbars="none" >
<com.lotusgallery.lotus.lotusgallery.HSVLayout
android:id="@+id/movieLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</HorizontalScrollView>

<ImageSwitcher android:id="@+id/image_switcher"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginTop="20dp" />

 

再定義預覽圖片顯示的 Layout 如下: (hsv.xml)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >

<ImageView android:id="@+id/movie_image"
android:layout_width="wrap_content"
android:layout_height="400dp"
android:layout_alignParentBottom="true" />

</RelativeLayout>

 

可以發現在 HorizontalScrollView 中放了一個自定義的 HSLayout 元件,這是一個客製化的 LinearLayout,可想見之後會放很多預覽圖片進去讓使用者可快速瀏覽,因此實作了一個 setAdapter() 方法,以便動態餵圖片給這個 Layout 元件。當把 Adapter 指定給 HSLayout 元件之後,HSLayout 便可取得 Adapter 中儲存的所有小圖,將其加到自己的顯示介面中,並對每一張圖片實作 onClick(),當圖片被點下後就會發出 intent 給對應的人處理,此例中就是 ImageSwitcher 。

其實作方法如下:

public class HSVLayout extends LinearLayout {
private Context mContext;

public HSVLayout(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
}

public void setAdapter(HSVAdapter adapter) {
for (int i = 0; i < adapter.getCount(); i++) {
final Map<String, Object> map = adapter.getItem(i);
View view = adapter.getView(i, null, null);
view.setPadding(10, 0, 10, 0);
view.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction(AppConstant.UPDATE_IMAGE_ACTION);
intent.putExtra("index", (Integer) map.get("index"));
mContext.sendBroadcast(intent);
}
});
this.setOrientation(HORIZONTAL);
this.addView(view, new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
}
}
}

 

HSVAdapter 繼承自 BaseAdapter,管理一個 List 來保存所有的預覽圖,利用 addObject() 方法加入到其中,透過 HSVAdapter 可抓取到所有預覽圖的 View 元件。

實作如下:

public class HSVAdapter extends BaseAdapter {
private List<Map<String, Object>> mList;
private Context mContext;

public HSVAdapter(Context context) {
mContext = context;
mList = new ArrayList<Map<String, Object>>();
}

@Override
public int getCount() {
return mList.size();
}

@Override
public Map<String, Object> getItem(int location) {
return mList.get(location);
}

@Override
public long getItemId(int arg0) {
return arg0;
}

public void addObject(Map<String, Object> map) {
mList.add(map);
notifyDataSetChanged();
}

@Override
public View getView(int location, View arg1, ViewGroup arg2) {
View view = LayoutInflater.from(mContext).inflate(R.layout.hsv, null);
ImageView image = (ImageView) view.findViewById(R.id.movie_image);
Map<String, Object> map = getItem(location);
image.setBackgroundResource((Integer) map.get("image"));
return view;
}
}

 

幹你娘打好多字喔,休息一下

 

最後在 MainActivity 的部分,為了實作 ImageSwitcher,必須去繼承 ViewFactory 並複寫 makeView 方法:

public class MainActivity extends ActionBarActivity implements ViewSwitcher.ViewFactory {
.....

@Override
public View makeView() {
ImageView imageView = new ImageView(getApplicationContext());
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
imageView.setLayoutParams(new ImageSwitcher.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
return imageView;
}

 

宣告所需的變數:

private ImageSwitcher mImgSwicher;
private HSVLayout mGalleryLayout;
private HSVAdapter mImgAdapter;
private IntentFilter mIntentFilter;
private BroadcastReceiver mReceiver;
private int mCount = 0;

 

宣告原始圖片與預覽圖片:

// 宣告原始圖片
private Integer[] imgArr = {
R.drawable.img01, R.drawable.img02, R.drawable.img03,
R.drawable.img04, R.drawable.img05, R.drawable.img06,
R.drawable.img07, R.drawable.img08};

// 宣告預覽圖片
private Integer[] thumbImgArr = {
R.drawable.img01th, R.drawable.img02th, R.drawable.img03th,
R.drawable.img04th, R.drawable.img05th, R.drawable.img06th,
R.drawable.img07th, R.drawable.img08th};

 

初始化 ImageSwitcher 並指定圖片切換動畫效果

mImgSwicher = (ImageSwitcher) findViewById(R.id.image_switcher);
mImgSwicher.setFactory(this);
mImgSwicher.setInAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_in));
mImgSwicher.setOutAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_out));

 

初始化 HSVLayout 與 HSVAdapter:

mGalleryLayout = (HSVLayout) findViewById(R.id.movieLayout);
mImgAdapter = new HSVAdapter(this);

 

將預覽圖餵給 HSVAdapter:

for (int i = 0; i < thumbImgArr.length; i++) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("image", thumbImgArr[i]);
map.put("index", (i+1));
mImgAdapter.addObject(map);
}

 

將 HSVAdapter 指定給 HSVLayout:

mGalleryLayout.setAdapter(mImgAdapter);

 

為 ImageSwitcher 設定 default 圖片:

mImgSwicher.setImageResource(imgArr[mCount]);

 

動態宣告 Internt filter:

private IntentFilter getIntentFilter() {
if (mIntentFilter == null) {
mIntentFilter = new IntentFilter();
mIntentFilter.addAction(AppConstant.UPDATE_IMAGE_ACTION);
}
return mIntentFilter;
}

在 onResume() 時註冊 Receiver 去監聽 HSVLayout 有沒有預覽圖被點擊,若有則通知 ImageSwitcher 切換到指定的原始圖片

@Override
protected void onResume() {
super.onResume();
if (mReceiver == null) {
mReceiver = new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(AppConstant.UPDATE_IMAGE_ACTION)) {
int index = intent.getIntExtra("index", Integer.MAX_VALUE);
mImgSwicher.setImageResource(imgArr[index-1]);
}
}
};
}
registerReceiver(mReceiver, getIntentFilter());
}

 

在 onPause() 時記得去做反註冊:

@Override
protected void onPause() {
super.onPause();
unregisterReceiver(mReceiver);
}

 

以上~ 

 

參考文件:

http://www.it165.net/pro/html/201310/7469.html

 

arrow
arrow
    全站熱搜

    擒猿小舖 發表在 痞客邦 留言(0) 人氣()