in Android Tutorial

Membuat Aplikasi Android News Menggunakan Swipe Refresh Layout dan Load More Data pada ListView (Paging)

 

SwipeRefreshLayout
SwipeRefreshLayout digunakan setiap kali pengguna me-refresh isi konten via gerakan menggesek vertikal. Kegiatan yang instantiates konten ini harus menambahkan OnRefreshListener untuk menyegarkan isi konten. SwipeRefreshLayout akan memberitahukan listener setiap kali gerakan, listener bertanggung jawab untuk menentukan kapan memulai refresh isinya. Jika listener menentukan tidak boleh ada refresh, itu harus memanggil setRefreshing(false) untuk membatalkan indikasi visual refresh. Jika suatu kegiatan ingin menunjukkan hanya kemajuan animasi, itu harus memanggil setRefreshing(true). Untuk menonaktifkan gerakan dan kemajuan animasi, sebut setEnabled(false) pada tampilan. Selengkapnya.

ListView
ListView adalah kelompok konten yang menampilkan daftar item. Daftar item secara otomatis dimasukkan ke dalam daftar tampilan menggunakan Adapter yang memanggil konten dari sumber seperti array atau database query dan mengubah hasil setiap item dalam tampilan yang ditempatkan ke dalam daftar tampilan. Selengkapnya.

Langkah awal dalam tutorial yaitu membuat database dengan nama kuncoro_news dengan nama tabel news dan struktur tabelnya seperti berikut :

Column name Data Type lenght Primary Key Not Null Auto Increment
id int 10 v v v
title varchar 250
value longtext
images varchar 250
date date

Membuat web service untuk parsing data ke aplikasi android.
koneksi.php
Sebagai koneksi aplikasi ke database. Coding-nya disini.

news.php
Untuk menampilkan daftar news. Coding-nya disini.

detail_news.php
Untuk menampilkan detail news. Coding-nya disini.

Buat project baru di Android Studio File ⇒ New Project. Kemudian pilih Empty Activity dan melanjutkannya hingga selesai.

news
 

activity_main.xml
Tampilan utama untuk menampilkan listview news.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/swipe_refresh_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <ListView
            android:id="@+id/list_news"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:divider="@color/list_divider"
            android:dividerHeight="2dp"
            android:listSelector="@drawable/list_row_selector" />

    </android.support.v4.widget.SwipeRefreshLayout>

</LinearLayout>

 

detail_news.xml
Untuk menampilkan detail dari news.

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/swipe_refresh_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#fff" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:padding="16dp" >

            <TextView
                android:id="@+id/judul_news"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textStyle="bold" />

            <TextView
                android:id="@+id/tgl_news"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />

            <com.android.volley.toolbox.NetworkImageView
                android:id="@+id/gambar_news"
                android:layout_gravity="center"
                android:layout_marginTop="5dp"
                android:layout_marginBottom="5dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:scaleType="fitXY" />

            <TextView
                android:id="@+id/isi_news"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

        </LinearLayout>
    </ScrollView>
</android.support.v4.widget.SwipeRefreshLayout>

 

list_row_news.xml
Untuk tampilan custom listview news.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="16dp"
    android:background="@drawable/list_row_selector">

    <TextView
        android:id="@+id/news_judul"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textStyle="bold"/>

    <TextView
        android:id="@+id/news_timestamp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <com.android.volley.toolbox.NetworkImageView
        android:id="@+id/news_gambar"
        android:layout_gravity="center"
        android:layout_marginTop="5dp"
        android:layout_marginBottom="5dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:scaleType="fitXY" />

    <TextView
        android:id="@+id/news_isi"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

 

Buat folder drawable didalam res dan isi file baru dengan nama list_row_bg.xml, list_row_bg_hover.xml, dan list_row_selector.xml sebagai style listview.
list_row_bg.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <gradient
        android:startColor="@color/list_row_start_color"
        android:endColor="@color/list_row_end_color"
        android:angle="270" />
</shape>

 

list_row_bg_hover.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >

    <gradient
        android:angle="270"
        android:endColor="@color/list_row_hover_end_color"
        android:startColor="@color/list_row_hover_start_color" />

</shape>

 

list_row_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/list_row_bg" android:state_pressed="false" android:state_selected="false"/>
    <item android:drawable="@drawable/list_row_bg_hover" android:state_pressed="true"/>
    <item android:drawable="@drawable/list_row_bg_hover" android:state_pressed="false" android:state_selected="true"/>
</selector>

 

Masuk folder res=>values=>color.xml dan tambahkan code seperti berikut :
color.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
    <color name="list_divider">#d9d9d9</color>
    <color name="list_row_start_color">#ffffff</color>
    <color name="list_row_end_color">#ffffff</color>
    <color name="list_row_hover_start_color">#ebeef0</color>
    <color name="list_row_hover_end_color">#ebeef0</color>
</resources>

 

Buka build.gradle dan tambahkan volley library didalamnya.

compile 'com.mcxiaoke.volley:library-aar:1.0.0'

 

build.gradle

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.2.0'
    compile 'com.android.support:design:23.2.0'
    compile 'com.mcxiaoke.volley:library-aar:1.0.0'
}

 

Agar project terstruktur dan terorganisir, buat 5 paket dengan nama adapter, app, data, util, dan volley. Untuk membuat paket baru , klik kanan pada src=>New=>Peckage dan memberikan nama paket . Contoh : com.kuncoro.kuncoronews.

struktur
 

Buat class dengan nama LruBitmapCache.java didalam package volley dan tambah coding seperti dibawah ini. Class ini berfingsi untuk mengatur caching network image dalam penyimpanan.
LruBitmapCache.java

package com.kuncoro.kuncoronews.volley;

import android.graphics.Bitmap;
import android.support.v4.util.LruCache;

import com.android.volley.toolbox.ImageLoader.ImageCache;

public class LruBitmapCache extends LruCache<String, Bitmap> implements
		ImageCache {
	public static int getDefaultLruCacheSize() {
		final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
		final int cacheSize = maxMemory / 8;

		return cacheSize;
	}

	public LruBitmapCache() {
		this(getDefaultLruCacheSize());
	}

	public LruBitmapCache(int sizeInKiloBytes) {
		super(sizeInKiloBytes);
	}

	@Override
	protected int sizeOf(String key, Bitmap value) {
		return value.getRowBytes() * value.getHeight() / 1024;
	}

	@Override
	public Bitmap getBitmap(String url) {
		return get(url);
	}

	@Override
	public void putBitmap(String url, Bitmap bitmap) {
		put(url, bitmap);
	}
}

 

Buat class AppController.java didalam package app dan tambah coding seperti dibawah ini. Class tunggal yang menginisialisasi class global yang diperlukan. Semua objek yang berhubungan dengan volley diinisialisasi di sini.
AppController.java

package com.kuncoro.kuncoronews.app;

import android.app.Application;
import android.text.TextUtils;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;
import com.kuncoro.kuncoronews.volley.LruBitmapCache;

public class AppController extends Application {

	public static final String TAG = AppController.class.getSimpleName();

	private RequestQueue mRequestQueue;
	private ImageLoader mImageLoader;
	LruBitmapCache mLruBitmapCache;

	private static AppController mInstance;

	@Override
	public void onCreate() {
		super.onCreate();
		mInstance = this;
	}

	public static synchronized AppController getInstance() {
		return mInstance;
	}

	public RequestQueue getRequestQueue() {
		if (mRequestQueue == null) {
			mRequestQueue = Volley.newRequestQueue(getApplicationContext());
		}

		return mRequestQueue;
	}

	public ImageLoader getImageLoader() {
		getRequestQueue();
		if (mImageLoader == null) {
			getLruBitmapCache();
			mImageLoader = new ImageLoader(this.mRequestQueue, mLruBitmapCache);
		}

		return this.mImageLoader;
	}

	public LruBitmapCache getLruBitmapCache() {
		if (mLruBitmapCache == null)
			mLruBitmapCache = new LruBitmapCache();
		return this.mLruBitmapCache;
	}

	public <T> void addToRequestQueue(Request<T> req, String tag) {
		req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
		getRequestQueue().add(req);
	}

	public <T> void addToRequestQueue(Request<T> req) {
		req.setTag(TAG);
		getRequestQueue().add(req);
	}

	public void cancelPendingRequests(Object tag) {
		if (mRequestQueue != null) {
			mRequestQueue.cancelAll(tag);
		}
	}

}

Buat class NewsData.java didalam package data dan tambahkan coding seperti dibawah ini. Class ini berfungsi sebagai membuat objek untuk setiap item yang diparsing JSON. Objek ini berisi informasi seperti id berita, judul berita, datetime berita, isi berita, data url gambar.
NewsData.java

package com.kuncoro.kuncoronews.data;

/**
 * Created by Kuncoro on 29/02/2016.
 */
public class NewsData {
    private String id, judul, datetime, isi, gambar;

    public NewsData() {
    }

    public NewsData(String id, String judul, String datetime, String isi, String gambar) {
        this.id = id;
        this.judul = judul;
        this.datetime = datetime;
        this.gambar = gambar;
        this.isi = isi;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getJudul() {
        return judul;
    }

    public void setJudul(String judul) {
        this.judul = judul;
    }

    public String getGambar() {
        return gambar;
    }

    public void setGambar(String gambar) {
        this.gambar = gambar;
    }

    public String getDatetime() {
        return datetime;
    }

    public void setDatetime(String datetime) {
        this.datetime = datetime;
    }

    public String getIsi() {
        return isi;
    }

    public void setIsi(String isi) {
        this.isi = isi;
    }

}

 

Buat class NewsAdapter.java didalam package adapter dan tambahkan coding seperti dibawah ini. Class ini berfungsi sebagai menampilkan data seperti id berita, judul berita, datetime berita, isi berita, data url gambar kemudian ditampilkan ke dalam listview.
NewsAdapter.java

package com.kuncoro.kuncoronews.adapter;

import android.app.Activity;
import android.content.Context;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.NetworkImageView;
import com.kuncoro.kuncoronews.R;
import com.kuncoro.kuncoronews.app.AppController;
import com.kuncoro.kuncoronews.data.NewsData;

import java.util.List;

/**
 * Created by Kuncoro on 29/02/2016.
 */
public class NewsAdapter extends BaseAdapter {
    private Activity activity;
    private LayoutInflater inflater;
    private List<NewsData> newsItems;
    ImageLoader imageLoader;

    public NewsAdapter(Activity activity, List<NewsData> newsItems) {
        this.activity = activity;
        this.newsItems = newsItems;
    }

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

    @Override
    public Object getItem(int location) {
        return newsItems.get(location);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        if (inflater == null)
            inflater = (LayoutInflater) activity
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        if (convertView == null)
            convertView = inflater.inflate(R.layout.list_row_news, null);

        if (imageLoader == null)
            imageLoader = AppController.getInstance().getImageLoader();

        NetworkImageView thumbNail = (NetworkImageView) convertView.findViewById(R.id.news_gambar);
        TextView judul = (TextView) convertView.findViewById(R.id.news_judul);
        TextView timestamp = (TextView) convertView.findViewById(R.id.news_timestamp);
        TextView isi = (TextView) convertView.findViewById(R.id.news_isi);

        NewsData news = newsItems.get(position);

        thumbNail.setImageUrl(news.getGambar(), imageLoader);
        judul.setText(news.getJudul());
        timestamp.setText(news.getDatetime());
        isi.setText(Html.fromHtml(news.getIsi()));

        return convertView;
    }

}

 

Buat class Server.java didalam package util dan tambahkan coding seperti dibawah ini. Class ini berfungsi mengatur link server sumber data dari web service yang akan digunakan.
Server.java

package com.kuncoro.kuncoronews.util;

/**
 * Created by Kuncoro on 29/02/2016.
 */
public class Server {
    // sesuaikan dengan IP Address PC/laptop atau ip address emulator android 10.0.2.2
    public static final String URL = "http://192.168.10.177/android/kuncoronews/";
}

 

Buka class MainActivity.java dan tambahkan coding seperti dibawah ini. Class ini berfungsi menampilkan data berita dalam listview dari web service volley JsonArrayRequest. Setelah diparsing, semua data JSON Array akan disimpan pada objek NewsData. Terakhir memanggil notifyDataSetChanged() untuk perubahan data pada NewsAdapter. Berita akan ditampilkan 10, kemudian akan load more apabila di scrolldown hingga muncul Widget Swipe Refresh Layout dalam beberapa detik kemudian data berita selanjutnya akan muncul.
MainActivity.java

package com.kuncoro.kuncoronews;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.ListView;

import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.VolleyLog;
import com.android.volley.toolbox.JsonArrayRequest;
import com.kuncoro.kuncoronews.adapter.NewsAdapter;
import com.kuncoro.kuncoronews.app.AppController;
import com.kuncoro.kuncoronews.data.NewsData;
import com.kuncoro.kuncoronews.util.Server;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Kuncoro on 29/02/2016.
 */
public class MainActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener {

    ListView list;
    SwipeRefreshLayout swipe;
    List<NewsData> newsList = new ArrayList<NewsData>();

    private static final String TAG = MainActivity.class.getSimpleName();

    private static String url_list 	 = Server.URL + "news.php?offset=";

    private int offSet = 0;

    int no;

    NewsAdapter adapter;

    public static final String TAG_NO       = "no";
    public static final String TAG_ID       = "id";
    public static final String TAG_JUDUL    = "judul";
    public static final String TAG_TGL      = "tgl";
    public static final String TAG_ISI      = "isi";
    public static final String TAG_GAMBAR   = "gambar";

    Handler handler;
    Runnable runnable;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        swipe = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_layout);
        list = (ListView) findViewById(R.id.list_news);
        newsList.clear();

        list.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                                    int position, long id) {
                // TODO Auto-generated method stub
                Intent intent = new Intent(MainActivity.this, DetailNews.class);
                intent.putExtra(TAG_ID, newsList.get(position).getId());
                startActivity(intent);
            }
        });

        adapter = new NewsAdapter(MainActivity.this, newsList);
        list.setAdapter(adapter);

        swipe.setOnRefreshListener(this);

        swipe.post(new Runnable() {
                       @Override
                       public void run() {
                           swipe.setRefreshing(true);
                           newsList.clear();
                           adapter.notifyDataSetChanged();
                           callNews(0);
                       }
                   }
        );

        list.setOnScrollListener(new AbsListView.OnScrollListener() {

            private int currentVisibleItemCount;
            private int currentScrollState;
            private int currentFirstVisibleItem;
            private int totalItem;

            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                this.currentScrollState = scrollState;
                this.isScrollCompleted();
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                this.currentFirstVisibleItem = firstVisibleItem;
                this.currentVisibleItemCount = visibleItemCount;
                this.totalItem = totalItemCount;
            }

            private void isScrollCompleted() {
                if (totalItem - currentFirstVisibleItem == currentVisibleItemCount
                        && this.currentScrollState == SCROLL_STATE_IDLE) {

                    swipe.setRefreshing(true);
                    handler = new Handler();

                    runnable = new Runnable() {
                        public void run() {
                            callNews(offSet);
                        }
                    };

                    handler.postDelayed(runnable, 3000);
                }
            }

        });

    }

    @Override
    public void onRefresh() {
        newsList.clear();
        adapter.notifyDataSetChanged();
        callNews(0);
    }

    private void callNews(int page){

        swipe.setRefreshing(true);

        // Creating volley request obj
        JsonArrayRequest arrReq = new JsonArrayRequest(url_list + page,
                new Response.Listener<JSONArray>() {
                    @Override
                    public void onResponse(JSONArray response) {
                        Log.d(TAG, response.toString());

                        if (response.length() > 0) {
                            // Parsing json
                            for (int i = 0; i < response.length(); i++) {
                                try {

                                    JSONObject obj = response.getJSONObject(i);
                                    NewsData news = new NewsData();

                                    no = obj.getInt(TAG_NO);

                                    news.setId(obj.getString(TAG_ID));
                                    news.setJudul(obj.getString(TAG_JUDUL));

                                    if (obj.getString(TAG_GAMBAR) != "") {
                                        news.setGambar(obj.getString(TAG_GAMBAR));
                                    }

                                    news.setDatetime(obj.getString(TAG_TGL));
                                    news.setIsi(obj.getString(TAG_ISI));

                                    // adding news to news array
                                    newsList.add(news);

                                    if (no > offSet)
                                        offSet = no;

                                    Log.d(TAG, "offSet " + offSet);

                                } catch (JSONException e) {
                                    Log.e(TAG, "JSON Parsing error: " + e.getMessage());
                                }

                                // notifying list adapter about data changes
                                // so that it renders the list view with updated data
                                adapter.notifyDataSetChanged();
                            }
                        }
                        swipe.setRefreshing(false);
                    }

                }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                VolleyLog.d(TAG, "Error: " + error.getMessage());
                swipe.setRefreshing(false);
            }
        });

        // Adding request to request queue
        AppController.getInstance().addToRequestQueue(arrReq);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

}

 

Buat class DetailNews.java yang berfungsi sebagai menampilkan detail data dari berita yang dipilih dari MainActivity.java.
DetailNews.java

package com.kuncoro.kuncoronews;

import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.text.Html;
import android.util.Log;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;

import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.NetworkImageView;
import com.android.volley.toolbox.StringRequest;
import com.kuncoro.kuncoronews.app.AppController;
import com.kuncoro.kuncoronews.util.Server;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by Kuncoro on 29/02/2016.
 */
public class DetailNews extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener {

    NetworkImageView thumb_image;
    TextView judul, tgl, isi;
    ImageLoader imageLoader = AppController.getInstance().getImageLoader();
    SwipeRefreshLayout swipe;
    String id_news;

    private static final String TAG = DetailNews.class.getSimpleName();

    public static final String TAG_ID 		= "id";
    public static final String TAG_JUDUL 	= "judul";
    public static final String TAG_TGL 		= "tgl";
    public static final String TAG_ISI 		= "isi";
    public static final String TAG_GAMBAR	= "gambar";

    private static final String url_detail 	= Server.URL + "detail_news.php";
    String tag_json_obj = "json_obj_req";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.detail_news);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        setTitle("Detail News");

        thumb_image = (NetworkImageView) findViewById(R.id.gambar_news);
        judul 		= (TextView) findViewById(R.id.judul_news);
        tgl 		= (TextView) findViewById(R.id.tgl_news);
        isi 		= (TextView) findViewById(R.id.isi_news);
        swipe       = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_layout);

        id_news = getIntent().getStringExtra(TAG_ID);

        swipe.setOnRefreshListener(this);

        swipe.post(new Runnable() {
                       @Override
                       public void run() {
                           if (!id_news.isEmpty()) {
                               callDetailNews(id_news);
                           }
                       }
                   }
        );

    }

    private void callDetailNews(final String id){
        swipe.setRefreshing(true);

        StringRequest strReq = new StringRequest(Request.Method.POST, url_detail, new Response.Listener<String>() {

            @Override
            public void onResponse(String response) {
                Log.d(TAG, "Response " + response.toString());
                swipe.setRefreshing(false);

                try {
                    JSONObject obj = new JSONObject(response);

                    String Judul    = obj.getString(TAG_JUDUL);
                    String Gambar   = obj.getString(TAG_GAMBAR);
                    String Tgl      = obj.getString(TAG_TGL);
                    String Isi      = obj.getString(TAG_ISI);

                    judul.setText(Judul);
                    tgl.setText(Tgl);
                    isi.setText(Html.fromHtml(Isi));

                    if (obj.getString(TAG_GAMBAR)!=""){
                        thumb_image.setImageUrl(Gambar, imageLoader);
                    }

                } catch (JSONException e) {
                    e.printStackTrace();
                }

            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e(TAG, "Detail News Error: " + error.getMessage());
                Toast.makeText(DetailNews.this,
                        error.getMessage(), Toast.LENGTH_LONG).show();
                swipe.setRefreshing(false);
            }
        }) {

            @Override
            protected Map<String, String> getParams() {
                // Posting parameters to post url
                Map<String, String> params = new HashMap<String, String>();
                params.put("id", id);

                return params;
            }

        };

        // Adding request to request queue
        AppController.getInstance().addToRequestQueue(strReq, tag_json_obj);
    }

    @Override
    public void onBackPressed() {
        finish();
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                this.finish();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public void onRefresh() {
        callDetailNews(id_news);
    }
}

 

Tambahkan perijinan INTERNET, ACCESS_NETWORK_STATE, android:name=”.app.AppController” pada application dan activity DetailNews pada AndroidManifest.xml.
AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.kuncoro.kuncoronews">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <application
        android:name=".app.AppController"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".DetailNews" />
    </application>

</manifest>

Run Aplikasinya.

 

Download Source Code :
 

Download

Please share 🙂


Share on FacebookTweet about this on TwitterShare on Google+Pin on PinterestShare on LinkedInEmail this to someone

Related Posts