ตัวอย่างการใช้ Picasso มาช่วยแก้ปัญหารูปภาพใน Android
วันนี้ขอนำเสนอบทความเกี่ยวกับ Image Library ครับ คือการใช้ Picasso มาช่วยแก้ปัญหาในการแสดงผลรูปภาพ ImageView กันครับ ก่อนหน้านี้ผมเคยพูดถึง Library อีกตัวไปแล้ว ที่ชื่อว่า Universal Image Loader
คุณเคยไหมที่เวลาใช้ ImageView บางครั้งโปรแกรมปิดตัว เกิดอาการ OutofMemory ต้องทำการปรับ BitmapFactory.Options
เอง นั่งคำนวณ ขนาดเอง หรือลดขนาดรูปภาพตามความเหมาะสม หรืออีกกรณีเวลาโหลดรูปภาพจากเว็บไซต์ อยากให้มัน cache ลงเครื่องด้วย โดยปกติเราจำเป็นต้องตั้งค่าและเขียนเองทั้งหมด เพื่อให้รองรับปัญหาต่างๆ วันนี้เจ้า Picasso มันจะมาแก้ปัญหาเหล่านี้ให้ท่านครับ
Picasso คืออะไร?
จากในเว็บเขียนอธิบายว่า A powerful image downloading and caching library for Android มันก็คือ Library ของแอนดรอยส์เกี่ยวกับการจัดการรูปภาพ ดาวน์โหลดรูปภาพ และมีการ cach รูปภาพให้นั่นเอง รายละเอียดเพิ่มเติม อ่านได้จากเว็บไซต์ต้นฉบับที่นี่ Picasso
เวอร์ชันในขณะเขียนบทความนี้คือ Picasso 2.3.2
ขั้นตอนการใช้งาน
มีด้วยกัน 2 ออปชั่น คือ จะโหลดเป็นไฟล์ .jar หรือว่าจะใช้ maven
โหลดแบบ .jar : ดาวน์โหลดโดยตรงได้จากลิงค์นี้ Download Picasso-2.3.2.jar หรือจะเข้าไปในหน้าเว็บไซต์หลัก แล้วเลือกส่วน Download ก็ได้
ใช้ maven
<dependency>
<groupId>com.squareup.picasso</groupId>
<artifactId>picasso</artifactId>
<version>2.3.2</version>
</dependency>
วิธีการใช้งานก็ง่ายมากๆ ตามโค๊ดนี้
Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);
with()
: โหลดด้วยContext
ของ activityload()
: parameter URI ของไฟล์, รูปใน drawable หรือว่า File ก็ได้into()
: parameter คือImageView
ที่เราต้องการจะให้มันแสดง
Options เพิ่มเติม ก็พวก
resize()
: สำหรับเปลี่ยนขนาดรูปcenterCrop()
: จัดภาพกึ่งกลางแบบ center cropplaceholder()
: สำหรับใส่รูป placeholdererror()
: ใส่รูป default กรณีที่เกิด error โหลดรูปไม่ได้transform()
: transform effectrotate()
: effect สำหรับหมุนรูปภาพ
ส่วน option อื่นๆ ก็ดูเพิ่มเติมที่เว็บไซต์หลักเลย ในส่วนรายละเอียดที่ไม่ได้เกี่ยวข้องกับ Picasso จะไม่ขอพูดถึงในบทความนี้นะครับ หากเรื่องไหนไม่เ้ข้าใจ ก็ลองค้นหาที่กล่องค้นหาของเว็บนี้ หรือ google ครับ
เริ่มต้นสร้างโปรเจ็ค
ทำการสร้างโปรเจ็คขึ้นมาใหม่ ในตัวอย่างนี้ผมใช้ Android Studio เมื่อสร้างโปรเจ็คใหม่ จะได้ไฟล์ structure ประมาณนี้
├── build
├── build.gradle
├── libs
├── proguard-rules.pro
└── src
├── androidTest
│ └── java
└── main
├── AndroidManifest.xml
├── java
└── com
└── devahoy
└── picassoexample
└── MainActivity.java
└── res
├── drawable-hdpi
├── drawable-mdpi
├── drawable-xhdpi
├── drawable-xxhdpi
├── layout
├── menu
├── values
└── values-w820dp
เปิด build.gradle
ขึ้นมาเพื่อทำการเพิ่ม Library เข้าไป ดังนี้
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:19.+'
compile 'com.squareup.picasso:picasso:2.3.2'
}
หากใครดาวน์โหลดแบบ .jar ไฟล์มา ก็ไม่ต้องเพิ่ม compile 'com.squareup.picasso:picasso:2.3.2'
แต่ว่าให้ก็อบไฟล์ .jar ไว้ในโฟลเดอร์ /libs
แทน เนื่องจากคอนฟิค fileTree ไว้แล้ว
สำหรับ Eclipse ก็ก็อบไฟล์ .jar ไว้ที่โฟลเดอร์
/libs
เช่นกัน แล้วคลิ๊กขวาเลือก Build Path -> Add to Build Path
เริ่มต้นทำแอพจริง
ตัวอย่างนี้คือจะโหลดรูปภาพจากเว็บไซต์ dribbble มาแสดงในแอพแบบ GridView เริ่มต้นผมก็ทำการสร้าง GridViewAdapter.java
ขึ้นมา และไฟล์เลเอาท์ ก็ใช้ activity_main.xml
อันเดิม ส่วน grid_item.xml
เอาไว้ปรับ ImageView ใน GridView
หากใครไม่เข้าใจ GridView ให้อ่านบทความนี้ประกอบ ตัวอย่างการใช้งาน GridView บน Android อย่างง่าย
ไฟล์ GridViewAdapter.java
เป็นแบบนี้
package com.devahoy.picassoexample;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import com.squareup.picasso.Picasso;
public class GridViewAdapter extends BaseAdapter {
private Context mContext;
private String[] mUrls;
private LayoutInflater mInflater;
public GridViewAdapter(Context context, String[] urls) {
mContext = context;
mUrls = urls;
mInflater = LayoutInflater.from(context);
}
public int getCount() {
return mUrls.length;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder viewHolder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.grid_item, parent, false);
viewHolder = new ViewHolder();
viewHolder.imageView = (ImageView)
convertView.findViewById(R.id.grid_item);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
Picasso.with(mContext).load(mUrls[position]).into(viewHolder.imageView);
return convertView;
}
public class ViewHolder {
ImageView imageView;
}
}
ส่วนไฟล์ activity_main.xml
เป็นแบบนี้
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<GridView
android:id="@+id/gridview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnWidth="80dp"
android:gravity="center"
android:verticalSpacing="0dp"
android:horizontalSpacing="0dp"
android:numColumns="auto_fit"
android:stretchMode="columnWidth"/>
</RelativeLayout>
และไฟล์ grid_item.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/grid_item"
android:layout_width="100dp"
android:layout_height="80dp"
android:scaleType="centerCrop"/>
</FrameLayout>
เพิ่มส่วน res/values/strings.xml
ไปนิดหน่อย
<string name="button_next">NEXT</string>
<string name="button_previous">PREVIOUS</string>
ส่วนสุดท้าย ไฟล์ MainActivity.java
ไม่มีอะไรมาก แค่สร้าง GridView
และ GridViewAdapter
เท่านั้น ก็จะได้แบบนี้
ไฟล์ MainActivity.java
package com.devahoy.picassoexample;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.GridView;
public class MainActivity extends ActionBarActivity {
private GridViewAdapter mAdapter;
private GridView mGridView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String[] urls = initSampleData();
mGridView = (GridView) findViewById(R.id.gridview);
mAdapter = new GridViewAdapter(this, urls);
mGridView.setAdapter(mAdapter);
}
private String[] initSampleData() {
return new String[] {
"https://d13yacurqjgara.cloudfront.net/users/3460/screenshots/1628158/animal-stickers_1x.png",
"https://d13yacurqjgara.cloudfront.net/users/14521/screenshots/1628431/designers_wanted_2_1x.png",
"https://d13yacurqjgara.cloudfront.net/users/57127/screenshots/1628433/kickstarterproject_1x.jpg",
"https://d13yacurqjgara.cloudfront.net/users/26059/screenshots/1628196/enter_1x.gif",
"https://d13yacurqjgara.cloudfront.net/users/32336/screenshots/1627983/dribbble3_1x.png",
"https://d13yacurqjgara.cloudfront.net/users/254554/screenshots/1628567/20140703--satellit2_1x.gif",
"https://d13yacurqjgara.cloudfront.net/users/144388/screenshots/1628118/table-creative-dribbble_1x.gif",
"https://d13yacurqjgara.cloudfront.net/users/13307/screenshots/1628973/logotypes_1x.jpg",
"https://d13yacurqjgara.cloudfront.net/users/45269/screenshots/1628472/workspace_1x.gif",
"https://d13yacurqjgara.cloudfront.net/users/124059/screenshots/1627992/search-filter_1x.gif",
"https://d13yacurqjgara.cloudfront.net/users/3375/screenshots/1628760/btt_cody_forever_1x.gif",
"https://d13yacurqjgara.cloudfront.net/users/79978/screenshots/1628721/koltozzbe.hu_2_1x.png",
"https://d13yacurqjgara.cloudfront.net/users/51395/screenshots/1628377/mercedes_minisite_1x.jpg",
"https://d13yacurqjgara.cloudfront.net/users/465131/screenshots/1628903/rpg_1x.jpg",
"https://d13yacurqjgara.cloudfront.net/users/267247/screenshots/1628670/prayer_app_1x.png",
"https://d13yacurqjgara.cloudfront.net/users/303896/screenshots/1628068/sitepreview_1x.png",
"https://d13yacurqjgara.cloudfront.net/users/9964/screenshots/1628170/crank-it-up_1x.png",
"https://d13yacurqjgara.cloudfront.net/users/155551/screenshots/1628228/icons_1x.png",
"https://d13yacurqjgara.cloudfront.net/users/38311/screenshots/1628047/dfst-mg4_1x.png",
"https://d13yacurqjgara.cloudfront.net/users/146798/screenshots/1628405/bubbly_birdy_1x.png",
"https://d13yacurqjgara.cloudfront.net/users/607501/screenshots/1628351/logo_mockup_display__07_1x.jpg",
"https://d13yacurqjgara.cloudfront.net/users/147435/screenshots/1628399/sufweb_teaser.jpg",
"https://d13yacurqjgara.cloudfront.net/users/111948/screenshots/1628041/rocket-pop_1x.jpg",
"https://d13yacurqjgara.cloudfront.net/users/157303/screenshots/1628313/12_1x.png",
"https://d13yacurqjgara.cloudfront.net/users/24711/screenshots/1628676/trivantis-city_2x_1x.png",
"https://d13yacurqjgara.cloudfront.net/users/604158/screenshots/1627943/final_1x.jpg",
"https://d13yacurqjgara.cloudfront.net/users/25416/screenshots/1628248/drib_1x.jpg",
"https://d13yacurqjgara.cloudfront.net/users/292484/screenshots/1628461/designers_guide_to_startup_weekend-1_1x.jpg",
"https://d13yacurqjgara.cloudfront.net/users/5976/screenshots/1628234/space_watchers_eye_planet_logo_design_symbol_by_alex_tass_teaser.jpg",
"https://d13yacurqjgara.cloudfront.net/users/271951/screenshots/1628799/thumb_1x.jpg",
"https://d13yacurqjgara.cloudfront.net/users/483231/screenshots/1628447/anicons1_1x.png",
"https://d13yacurqjgara.cloudfront.net/users/16540/screenshots/1628044/engage.independence.dribbb_1x.jpg"
};
}
}
url ของรูปภาพผมใช้รูปภาพจากการ api ของ dribbble นะครับ
อ้อเมื่อต่อ internet ก็อย่าลืมเพิ่ม permission internet ที่ไฟล์ AndroidManifest.xml
ด้วยละ
<uses-permission android:name="android.permission.INTERNET" />
สุดท้ายเมื่อรันโปรแกรม จะได้หน้าตาแบบนี้
ลองไปลองเล่นกันดูนะครับ
- Authors
- Name
- Chai Phonbopit
- Website
- @Phonbopit