Indonesian (Bahasa Indonesia) translation by Sandi Muamar (you can also view the original English article)

Pengenalan
Dalam tutorial ini, saya akan menunjukkan Anda mungkin menggunakan kasus apa yang kita pelajari di artikel sebelumnya tentang Volley. Kita akan membuat aplikasi cuaca untuk Mars, menggunakan informasi yang dikumpulkan oleh Curiosity rover, yang dibuat tersedia untuk semua orang oleh NASA melalui API {MAAS}.
Pertama, kita akan mengatur proyek di Android Studio dan desain user interface. Kami kemudian akan struktur inti dari aplikasi yang menggunakan Volley. Karena setiap aplikasi yang indah memiliki beberapa gambar, saya akan menunjukkan kepada Anda bagaimana untuk mengambil satu acak menggunakan Flickr API. Kami akan men-download gambar dengan Volley, sebagian besar karena sistem caching yang keren. Akhirnya, kita akan menambahkan beberapa rincian yang mewah untuk memberikan aplikasi yang cantik tampilan dan nuansa.
1. proyek Setup
Pertama, membuat proyek baru di Android Studio. Karena Volley backward compatible, Anda dapat memilih tingkat API apa pun yang Anda inginkan. Aku memilih untuk API 21, tetapi Anda harus halus selama sebagai tingkat API adalah 8 (Froyo) atau lebih tinggi.
Langkah 1: User Interface
Aplikasi kami memiliki acitivty, tunggal sederhana. Anda dapat menyebutnya MainActivity.java, seperti yang disarankan oleh Android Studio. Buka layout editor dan klik dua kali activity_main.xml.
Karena kami ingin memiliki sekitar 70% dari layar yang didedikasikan untuk gambar dan sisanya untuk informasi cuaca, kita perlu menggunakan XML atribut layout_weight
. Tentu saja, kita dapat menggunakan nilai-nilai mutlak juga, tapi itu tidak akan sama. Sayangnya, fitur-fitur Android world menampilkan yang apa-apa tapi homogen, dan menentukan nilai mutlak untuk tinggi gambar dapat menyebabkan rasio 90-10 pada perangkat sangat kecil dan 70-30, atau bahkan relasi 60-40, pada perangkat yang lebih besar. layout_weight
atribut adalah apa yang Anda butuhkan untuk memecahkan masalah inil
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <RelativeLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="0.68" android:background="#FF5722"> <!-- image --> </RelativeLayout> <RelativeLayout android:layout_weight="0.33" android:layout_height="0dp" android:layout_width="match_parent" android:paddingTop="@dimen/activity_horizontal_margin" android:background="#212121"> <!-- TextViews --> </RelativeLayout> </LinearLayout>
Di dalam first child Tambahkan ImageView
:
<ImageView android:id="@+id/main_bg" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop"/>
Dalam RelativeLayout
kedua, kami menambahkan daftar item TextView
. Dua dari mereka yang dilihat di mana suhu rata-rata dan suasana opacity ditampilkan. Yang ketiga adalah label kesalahan.
<TextView android:id="@+id/error" android:layout_centerInParent="true" android:visibility="gone" android:layout_height="wrap_content" android:layout_width="match_parent" android:textSize="20sp" android:textColor="#FF5722" android:layout_margin="@dimen/activity_horizontal_margin" android:gravity="center" android:text="I'm sorry.\nI wasn't able to retrieve real time data."/> <TextView android:id="@+id/degrees" android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_centerHorizontal="true" android:textSize="90sp" android:textColor="#FF5722" android:text="-36°"/> <TextView android:id="@+id/weather" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_below="@id/degrees" android:textSize="30sp" android:gravity="center" android:textColor="#FF5722" android:text="Sunny"/>
Tata letak sekarang harusnya lengkap. Anda dapat menambahkan rincian lebih lanjut jika Anda inginkan, tapi user interface yang kompleks dan rinci yang tidak dalam cakupan tutorial ini.
Langkah 2: Tema dan Permission
Ada dua hal lagi yang kita perlu untuk mengurus sebelum memulai untuk menggali ke dalam inti aplikasi. Mengubah tema warisan aplikasi untuk android:Theme.Material.Light.NoActionBar.
Ini berarti bahwa kita tidak perlu menyembunyikan action bar pada run time.
<style name="AppTheme" parent="android:Theme.Material.Light.NoActionBar"/>
Akhirnya, tambahkan permission internet ke proyek manifest.
<uses-permission android:name="android.permission.INTERNET" />
2. aplikasi inti
Langkah 1: Impor Volley
Seperti yang kita bahas di artikel sebelumnya, cara yang paling sederhana dan paling dapat diandalkan untuk menggunakan Volley adalah dengan mengimpor perpustakaan sebagai modul baru. Men-download kode sumber Perpustakaan, impor melalui File > New > Module, dan memberitahu kompilator di proyek build.gradle file untuk memasukkannya ke dalam proyek.
compile project(":volley")
Langkah 2: Menerapkan Helper Class
Seperti saya sudah tunjukkan dalam artikel sebelumnya, jika Anda perlu untuk memanggil beberapa request, itu lebih baik untuk menggunakan shared request queue. Anda harus menghindari membuat suatu antrian permintaan setiap kali Anda menjadwalkan permintaan dengan menerapkan Volley.newRequestQueue
, karena Anda tidak ingin berakhir dengan memory leak dan masalah lain yang tidak diinginkan.
Untuk melakukannya, pertama Anda harus membuat sebuah kelas yang menggunakan pola singleton. Kelas ini direferensikan menggunakan variabel statis, global terlihat, yang kemudian menangani objek RequestQueue
. Dengan cara ini, Anda berakhir dengan satu RequestQueue
untuk aplikasi. Kemudian, extend kelas Application
, Anda harus memberitahu untuk sistem operasi untuk menghasilkan objek ini saat startup aplikasi, bahkan sebelum activity pertama dibuat.
Karena kita berada di Android environment, kami sedikit mengubah struktur singleton umum. Kelas perlu membuat sebuah instance baru dari dirinya sendiri dalam metode Application.onCreate
— tidak dalam metode generik getInstance
yang ketika itu null
.
Untuk mencapai ini, membuat sebuah class baru dan nama itu MarsWeather.java. Selanjutnya, extend kelas Application
Android, meng-override metode onCreate
, dan menginisialisasi objek RequestQueue
contoh statis.
Di kelas singleton, kami membangun objek kelas menggunakan getInstance
fungsi public
dan synchronized
. Dalam metode ini, kita kembali mInstance
variabel. Metode onCreate
yang dipanggil saat aplikasi dimulai sehingga variabel mInstance
akan sudah ditetapkan pertama kalinya metode getInstance
yang dipanggil.
public class MarsWeather extends Application { private RequestQueue mRequestQueue; private static MarsWeather mInstance; @Override public void onCreate() { super.onCreate(); mInstance = this; mRequestQueue = Volley.newRequestQueue(getApplicationContext()); } public static synchronized MarsWeather getInstance() { return mInstance; } }
Selanjutnya, mengatakan dalam AndroidManifest.xml file yang Anda ingin MarsWeather
akan dimuat pada startup aplikasi. Dalam <application>
tag, menambahkan name
atribut sebagai berikut:
android:name=".MarsWeather"
Thats it. Instance kelas Application
dibuat, bahkan sebelum MainActivity
dibuat. Bersama dengan semua lain standar operasi, onCreate
menghasilkan sebuah instance dari RequestQueue
.
Kita perlu menerapkan tiga metode lain untuk menyelesaikan kelas helper. Metode pertama menggantikan Volley.newRequestQueue
, yang aku akan dinamai getRequestQueue
. Kami juga membutuhkan sebuah metode untuk menambahkan permintaan untuk antrian, add
, dan metode yang bertanggung jawab untuk membatalkan permintaan, cancel
. Blok kode berikut menunjukkan apa yang tampak seperti implementasi.
public RequestQueue getRequestQueue() { return mRequestQueue; } public <T> void add(Request<T> req) { req.setTag(TAG); getRequestQueue().add(req); } public void cancel() { mRequestQueue.cancelAll(TAG); }
TAG
adalah tanda generik yang Anda gunakan untuk mengidentifikasi permintaan. Dalam kasus khusus ini, dapat menjadi apa pun yang Anda inginkan:
public static final String TAG = MarsWeather.class.getName();
Langkah 3: Menerapkan Custom Request
Seperti yang Anda sudah tahu, Volley menyediakan tiga jenis standar permintaan: StringRequest
, ImageRequest
dan JsonRequest
. Aplikasi kita akan menggunakan yang kedua untuk mengambil data cuaca dan mengambil daftar gambar acak.
Secara default, Volley menetapkan prioritas dari permintaan ke NORMAL
. Biasanya itu akan baik-baik saja, tapi dalam aplikasi kita, kita memiliki dua permintaan yang sangat berbeda dan oleh karena itu kita perlu memiliki prioritas berbeda dalam antrian. Pengambilan data cuaca harus memiliki prioritas yang lebih tinggi daripada mengambil URL gambar acak.
Untuk alasan itu, kita perlu menyesuaikan kelas JsonRequest
. Membuat sebuah class baru yang bernama CustomJsonRequest.java, dan memastikan extend JsonObjectRequest
. Selanjutnya, override metode getPriority
seperti yang ditunjukkan di bawah ini.
public class CustomJsonRequest extends JsonObjectRequest { public CustomJsonRequest(int method, String url, JSONObject jsonRequest, Response.Listener<JSONObject> listener, Response.ErrorListener errorListener) { super(method, url, jsonRequest, listener, errorListener); } private Priority mPriority; public void setPriority(Priority priority) { mPriority = priority; } @Override public Priority getPriority() { return mPriority == null ? Priority.NORMAL : mPriority; } }
Langkah 4: Pengambilan Data
Kami akhirnya tiba pada bagian yang paling menarik dari tutorial ini di mana kita menulis implementasi untuk mengambil data cuaca. Akhir dari permintaan adalah:
http://marsweather.ingenology.com/v1/latest/
Api dapat ditelusuri jadi buka link untuk memeriksa JSON yang dihasilkan. JSON berisi sebuah objek yang sederhana, result
, yang meliputi serangkaian string, mulai dari suhu untuk angin arah dan waktu matahari terbenam.
Mulai dengan mendeklarasikan variabel berikut dalam kelas MainActivity
:
TextView mTxtDegrees, mTxtWeather, mTxtError; MarsWeather helper = MarsWeather.getInstance(); final static string RECENT_API_ENDPOINT = "http://marsweather.ingenology.com/v1/latest/";
Anda dapat memanggil MarsWeather.getInstance
di luar onCreate
. Karena kelas akan sudah diinisialisasi, Anda tidak perlu menunggu untuk metode onStart
memanggilnya. Tentu saja, Anda harus menetapkan referensi user interface dilihat dalam metode onCreate
.
mTxtDegrees = (TextView) findViewById(R.id.degrees); mTxtWeather = (TextView) findViewById(R.id.weather); mTxtError = (TextView) findViewById(R.id.error);
Setelah melakukan hal itu, saatnya untuk menerapkan metode loadWeatherData
. Kami membuat custom Volley request dan menetapkan prioritas HIGH
. Kita kemudian memanggil helper add
metode untuk menambahkannya ke queue permintaan. Hal yang penting untuk dicatat adalah result listener, karena hal itu akan mempengaruhi user interface.
private void loadWeatherData() { CustomJsonRequest request = new CustomJsonRequest (Request.Method.GET, RECENT_API_ENDPOINT, null, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { try { String minTemp, maxTemp, atmo; int avgTemp; response = response.getJSONObject("report"); minTemp = response.getString("min_temp"); minTemp = minTemp.substring(0, minTemp.indexOf(".")); maxTemp = response.getString("max_temp"); maxTemp = maxTemp.substring(0, maxTemp.indexOf(".")); avgTemp = (Integer.parseInt(minTemp)+Integer.parseInt(maxTemp))/2; atmo = response.getString("atmo_opacity"); mTxtDegrees.setText(avgTemp+"°"); mTxtWeather.setText(atmo); } catch (Exception e) { txtError(e); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { txtError(error); } }); request.setPriority(Request.Priority.HIGH); helper.add(request); }
Seperti yang Anda lihat, metode membutuhkan suhu minimum dan maksimum, menghitung rata-rata suhu, dan memperbarui user interface. Saya juga menerapkan sebuah metode sederhana untuk menangani kesalahan.
private void txtError(Exception e) { mTxtError.setVisibility(View.VISIBLE); e.printStackTrace(); }
Sekarang kita hanya perlu memanggil loadWeatherData
di onCreate
dan Anda sudah selesai. App sekarang siap untuk menunjukkan cuaca Mars.
3. mengambil Data gambar
Sekarang bahwa Anda memiliki core app siap dan bisa dipakai, kita dapat berfokus pada pembuatan aplikasi secara visual lebih menarik. Kami akan melakukan ini dengan mengambil gambar Mars secara acak dan menampilkannya kepada user.
Langkah 1: Mengambil gambar acak
Anda akan membutuhkan Flickr API key untuk mengambil daftar acak gambar kontekstual. endpoint gambar adalah sebagai berikut:
https://api.flickr.com/services/rest/?format=json&nojsoncallback=1& sort=random&method=flickr.photos.search&tags=mars,planet,rover&tag_mode=all& api_key=[YOUR_KEY]
Seperti yang Anda lihat, request tersebut cukup sederhana. Anda mengatakan Flickr untuk memberikan hasil yang diformat sebagai JSON (format = json
), tetapi kita tidak menentukan JSON callback (nojsoncallback = 1
). Anda mencari gambar (method=flickr.photos.search)
dan tag Anda tertarik terkait dengan Mars (tags = mars, planet, rover
). Lihatlah dokumentasi untuk informasi lebih lanjut tentang format URL request.
Mulai dengan mendeklarasikan variabel berikut:
final static String FLICKR_API_KEY = "[INSERT HERE YOUR API KEY]", IMAGES_API_ENDPOINT = "https://api.flickr.com/services/rest/?format=json&nojsoncallback=1&sort=random&method=flickr.photos.search&" + "tags=mars,planet,rover&tag_mode=all&api_key=";
Selanjutnya, menerapkan metode yang searchRandomImage
:
private void searchRandomImage() throws Exception { if (FLICKR_API_KEY.equals("")) throw new Exception("You didn't provide a working Flickr API!"); CustomJsonRequest request = new CustomJsonRequest (Request.Method.GET, IMAGES_API_ENDPOINT+ FLICKR_API_KEY, null, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { try { JSONArray images = response.getJSONObject("photos").getJSONArray("photo"); int index = new Random().nextInt(images.length()); JSONObject imageItem = images.getJSONObject(index); String imageUrl = "http://farm" + imageItem.getString("farm") + ".static.flickr.com/" + imageItem.getString("server") + "/" + imageItem.getString("id") + "_" + imageItem.getString("secret") + "_" + "c.jpg"; // TODO: do something with *imageUrl* } catch (Exception e) { imageError(e); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { imageError(error); } }); request.setPriority(Request.Priority.LOW); helper.add(request); }
Seperti yang Anda lihat, Flickr mengirim kembali JSONArray
yang berisi gambar. Metode yang saya tulis untuk mengambil gambar secara acak menghasilkan nomor acak antara nol dan dengan ukuran array. Dibutuhkan item sesuai index dari array hasil dan konstruksi URL untuk gambar dengan mengikuti panduan ini.
Seperti sebelumnya, kita membutuhkan sebuah metode untuk error handling:
int mainColor = Color.parseColor("#FF5722"); private void imageError(Exception e) { mImageView.setBackgroundColor(mainColor); e.printStackTrace(); }
Akhirnya, panggil searchRandomImage
dalam metode onCreate
dan jangan lupa untuk catch semua exception.
Langkah 2: Tampilkan gambar
Sekarang bahwa kita memiliki sebuah URL untuk memuat, kita dapat menampilkan gambar. Anda belajar bagaimana melakukan hal ini dalam artikel sebelumnya.
private void loadImg(String imageUrl) { // Retrieves an image specified by the URL, and displays it in the UI ImageRequest request = new ImageRequest(imageUrl, new Response.Listener<Bitmap>() { @Override public void onResponse(Bitmap bitmap) { mImageView.setImageBitmap(bitmap); } }, 0, 0, ImageView.ScaleType.CENTER_CROP, Bitmap.Config.ARGB_8888, new Response.ErrorListener() { public void onErrorResponse(VolleyError error) { imageError(error); } }); // we don't need to set the priority here; // ImageRequest already comes in with // priority set to LOW, that is exactly what we need. helper.add(request); }
Dalam metode onResponse
kita menulis di langkah sebelumnya, kami akhirnya mampu menangani result.
loadImg(imageUrl);
Langkah 3: Menampilkan gambar baru setiap hari
Mungkin Anda sudah menyadari bahwa kita melewati sistem caching Volley dengan mengambil gambar secara acak setiap kali aplikasi diluncurkan. Kita perlu menemukan cara untuk menunjukkan gambar yang sama pada hari tertentu.
Cara termudah untuk mencapai hal ini adalah dengan menggunakan Android SharedPreferences
. Mulailah dengan mendeklarasikan variabel-variabel yang akan kita butuhkan untuk ini.
SharedPreferences mSharedPref; int today = Calendar.getInstance().get(Calendar.DAY_OF_MONTH); final static String SHARED_PREFS_IMG_KEY = "img", SHARED_PREFS_DAY_KEY = "day";
Selanjutnya, dalam metode onCreate
, sebelum memanggil searchRandomImage
, menginisialisasi mSharedPref
.
mSharedPref = getPreferences(Context.MODE_PRIVATE);
Idenya adalah untuk menyimpan hari setiap kali kita mengambil gambar acak baru. Tentu saja, kami menyimpan URL gambar dan hari. Ketika meluncurkan aplikasi, kami memeriksa apakah kita sudah memiliki entri di SharedPreferences
untuk hari ini. Jika kita ada, kami menggunakan URL disimpan. Jika kita mengambil gambar secara acak dan menyimpan URL-nya di SharedPreferences
.
Dalam searchRandomImage
, setelah definisi imageUrl
, tambahkan baris berikut kode:
// right after *String imageUrl = .... * // store the pict of the day SharedPreferences.Editor editor = mSharedPref.edit(); editor.putInt(SHARED_PREFS_DAY_KEY, today); editor.putString(SHARED_PREFS_IMG_KEY, imageUrl); editor.commit(); // and then there's *loadImage(imageUrl);*
Metode onCreate
, setelah definisi pada mSharedPref
, sekarang menjadi:
if (mSharedPref.getInt(SHARED_PREFS_DAY_KEY, 0) != today) { // search and load a random mars pict try { searchRandomImage(); } catch (Exception e) { // please remember to set your own Flickr API! // otherwise I won't be able to show // a random Mars picture imageError(e); } } else { // we already have a pict of the day: let's load it loadImg(mSharedPref.getString(SHARED_PREFS_IMG_KEY, "")); } loadWeatherData();
Thats it. Aplikasi Anda sudah siap. Jangan ragu untuk men-download source file tutorial ini di GitHub untuk melihat proyek yang sudah selesai. Lihatlah proyek ini jika Anda menjalankan ke masalah.
Bonus Tip: Meningkatkan antarmuka pengguna
Langkah 1: Font
Font yang digunakan dalam antarmuka pengguna yang sering menentukan tampilan dan nuansa dari aplikasi. Mari kita mulai dengan mengubah font default Roboto dengan font yang lebih menarik, seperti Lato light.
Buat folder baru bernama fonts di folder assets. Jika Anda tidak dapat menemukan folder assets, Anda harus membuat ini pada tingkat yang sama sebagai folder java. Struktur folder harus melihat sesuatu seperti app\src\main\assets\fonts.
Menyalin file Lato-light.ttf dalam folder fonts. Dalam metode onCreate
, Anda perlu mengganti huruf default view di mana Anda ingin menggunakan font baru.
mTxtDegrees.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/Lato-light.ttf")); mTxtWeather.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/Lato-light.ttf"));
Langkah 2: Transparan Status Bar
Mengikuti pedoman untuk Android Material Design, kami dapat membuat status bar transparan. Dengan cara ini, latar belakang akan terlihat sebagian melalui status bar.
Anda dapat mencapai ini dengan membuat perubahan kecil dalam aplikasi tema. Mengedit file v21\style.xml proyek seperti ini:
<resources> <style name="AppTheme" parent="android:Theme.Material.Light.NoActionBar"> <item name="android:windowTranslucentStatus">true</item> </style> </resources>
Pastikan bahwa AndroidManifest.xml telah diatur untuk menggunakan tema:
<application android:name=".MarsWeather" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" >
Kesimpulan
Kami membuat perjalanan panjang. Dalam artikel pertama, kami mulai berbicara tentang Volley dan aplikasinya. Dalam tutorial ini, kita melihat cara praktis untuk menerapkan konsep-konsep yang kita pelajari dengan membangun aplikasi cuaca Mars. Anda sekarang harus memiliki pemahaman yang baik tentang voli Perpustakaan, cara kerjanya, dan apa yang dapat Anda gunakan
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Update me weeklyEnvato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!
Translate this post