編輯:關於Android編程
大家都用過viewpager了, github上有對viewpager進行擴展,導航風格更加豐富,這個開源項目是ViewPagerIndicator,很好用,但是例子比較簡單,實際用起來要進行很多擴展,比如在fragment裡進行圖片緩存和圖片異步加載。
下面是ViewPagerIndicator源碼運行後的效果,大家也都看過了,我多此一舉截幾張圖;
下載源碼請點擊這裡
<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+PGJyPgo8L3A+CjxwPjxicj4KPC9wPgo8cD48YnI+CjwvcD4KPHA+PGJyPgo8L3A+CjxwPjxicj4KPC9wPgo8cD49PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09u6rA9rXEt9a47s/fPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTwvcD4KPHA+PGJyPgo8L3A+CjxwPs/Cw+bKx87SuMTXsLn9tcSjrL/J0uyyvbzT1NjNvMaso6y/yc28xqy7urTmo7o8L3A+CjxwPjxpbWcgc3JjPQ=="/uploadfile/Collfiles/20140615/20140615094106112.jpg" alt="\">
看到美女你心動了沒有呢?
package com.example.viewpagerindicatortest; import java.util.ArrayList; import java.util.List; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; import com.viewpagerindicator.TabPageIndicator; /** * 基於Fragment的Tab樣式的viewpager; * * @author andy * * 更多詳情請訪問博客:http://blog.csdn.net/lyc66666666666 */ public class SampleTabsDefault extends FragmentActivity { //tab標題 private static final String[] CONTENT = new String[] { "Recent", "Artists", "Albums", "Songs", "Playlists", "Genres" ,"test"}; private Listlist = new ArrayList (); String[] urls = new String[] { "http://a.hiphotos.baidu.com/image/pic/item/3bf33a87e950352ad6465dad5143fbf2b2118b6b.jpg", "http://a.hiphotos.baidu.com/image/pic/item/c8177f3e6709c93d002077529d3df8dcd0005440.jpg", "http://f.hiphotos.baidu.com/image/pic/item/7aec54e736d12f2ecc3d90f84dc2d56285356869.jpg", "http://e.hiphotos.baidu.com/image/pic/item/9c16fdfaaf51f3de308a87fc96eef01f3a297969.jpg", "http://d.hiphotos.baidu.com/image/pic/item/f31fbe096b63f624b88f7e8e8544ebf81b4ca369.jpg", "http://h.hiphotos.baidu.com/image/pic/item/11385343fbf2b2117c2dc3c3c88065380cd78e38.jpg", "http://c.hiphotos.baidu.com/image/pic/item/3801213fb80e7bec5ed8456c2d2eb9389b506b38.jpg" }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.simple_tabs); /* * 初始化:組裝多個fragment * 第一次創建subfragment不會執行onCreateView方法 */ for (int i = 0; i < 7; i++) { SubFragment fragment =new SubFragment(urls[i]); list.add(fragment); } ViewPager pager = (ViewPager)findViewById(R.id.pager); pager.setAdapter(new MyAdapter(getSupportFragmentManager(),list));//設置適配器 TabPageIndicator indicator = (TabPageIndicator)findViewById(R.id.indicator); indicator.setViewPager(pager);// } /** * FragmentPagerAdapter用來適配Fragment */ class MyAdapter extends FragmentPagerAdapter { List mList; public MyAdapter(FragmentManager fm,List list) { super(fm); mList = list; } /** * FragmentPagerAdapter初始化item的時候會調用一次getItem, * 而第二次返回item則不調用getItem方法,而是執行SubFragment的onCreateView方法; * 也就是說只有在與fragment關聯的時候會調用一次getItem,以後則不調用; */ @Override public Fragment getItem(int position) { return mList.get(position); } /* * 返回title */ @Override public CharSequence getPageTitle(int position) { return CONTENT[position % CONTENT.length].toUpperCase(); } /* * 返回總頁數 */ @Override public int getCount() { return mList.size(); } } }
package com.example.viewpagerindicatortest; import java.io.IOException; import java.lang.ref.SoftReference; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.CoreConnectionPNames; import android.annotation.SuppressLint; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; /** * 基於Fragment的Tab樣式的viewpager; * * @author andy * * 更多詳情請訪問博客:http://blog.csdn.net/lyc66666666666 */ @SuppressLint("ValidFragment") public class SubFragment extends Fragment { private static final String KEY_CONTENT = "TestFragment:Content"; private String mContent = "???"; private String url; public SubFragment(String url) { this.url = url; System.out.println("url:"+url); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if ((savedInstanceState != null) && savedInstanceState.containsKey(KEY_CONTENT)) { mContent = savedInstanceState.getString(KEY_CONTENT); } } View v ; /** * 每次翻頁都會調用onCreateView創建一次組件 */ @Override public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) { v = inflater.inflate(R.layout.test, null); new AsyncImageLoader().loadDrawable(url, new ImageCallback() { @SuppressLint("NewApi") public void imageLoaded(Drawable imageDrawable, String imageUrl) { System.out.println("圖片獲取完成"); ImageView image = (ImageView) v.findViewById(R.id.img); image.setBackground(imageDrawable); } }); return v; } /** * 定義回調接口 */ public interface ImageCallback { public void imageLoaded(Drawable imageDrawable, String imageUrl); } /** * 異步加載圖片 */ static class AsyncImageLoader { Global global; public AsyncImageLoader() { global = Global.getInstance(); } /** * 創建子線程加載圖片 * 子線程加載完圖片交給handler處理(子線程不能更新ui,而handler處在主線程,可以更新ui) * handler又交給imageCallback,imageCallback須要自己來實現,在這裡可以對回調參數進行處理 * * @param imageUrl :須要加載的圖片url * @param imageCallback: * @return */ public Drawable loadDrawable(final String imageUrl, final ImageCallback imageCallback) { //如果緩存中存在圖片 ,則首先使用緩存 if (global.getCache(imageUrl)!=null) { System.out.println("存在緩存~~~~~~~~~~~~~~~~~"); SoftReferencesoftReference = global.getCache(imageUrl); Drawable drawable = softReference.get(); if (drawable != null) { imageCallback.imageLoaded(drawable, imageUrl);//執行回調 return drawable; } } /** * 在主線程裡執行回調,更新視圖 */ final Handler handler = new Handler() { public void handleMessage(Message message) { imageCallback.imageLoaded((Drawable) message.obj, imageUrl); } }; /** * 創建子線程訪問網絡並加載圖片 ,把結果交給handler處理 */ new Thread() { @Override public void run() { Drawable drawable = loadImageFromUrl(imageUrl); // 下載完的圖片放到緩存裡 global.setCache(imageUrl, new SoftReference (drawable)); Message message = handler.obtainMessage(0, drawable); handler.sendMessage(message); } }.start(); return null; } /** * 下載圖片 (注意HttpClient 和httpUrlConnection的區別) */ public Drawable loadImageFromUrl(String url) { try { HttpClient client = new DefaultHttpClient(); client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 1000*15); HttpGet get = new HttpGet(url); HttpResponse response; response = client.execute(get); if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { HttpEntity entity = response.getEntity(); Drawable d = Drawable.createFromStream(entity.getContent(), "src"); return d; } else { return null; } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putString(KEY_CONTENT, mContent); } }
package com.example.viewpagerindicatortest; import java.lang.ref.SoftReference; import java.util.HashMap; import android.graphics.drawable.Drawable; /** * 全局變量,以軟引用方式存放圖片緩存 * * @author andy * * 更多詳情請訪問博客:http://blog.csdn.net/lyc66666666666 */ public class Global { // 軟引用,使用內存做臨時緩存 (程序退出,或內存不夠則清除軟引用) private static HashMap> imageCache; private static Global global; public static Global getInstance() { if (global == null) { global = new Global(); } if (imageCache == null) { imageCache = new HashMap >(); } return global; } //存放緩存 public void setCache(String url, SoftReference softReference) { imageCache.put(url, softReference); } //獲取緩存 public SoftReference getCache(String url) { return imageCache.get(url); } //清除緩存 public void clearCache() { if (imageCache.size() > 0) { imageCache.clear(); } } }
simple_tabs.xml
test.xml
AndroidMainfest.xml
點擊下載源碼
先看效果圖: 控件類: import android.content.Context;import android.util.AttributeSet
1.初始使用android:completionThreshold="1"的作用是提示功能從第一個字母開始package com.treasure_c
前言距離寫上一篇自定義View文章已經大半年過去了,一直想繼續寫,但是無奈技術有限,生怕誤人子弟。這段時間項目剛剛完成,有點時間,跟著大神的腳步,鞏固下自定義View的相
Android Volley 是Google開發的一個網絡lib,可以讓你更加簡單並且快速的訪問網絡數據。Volley庫的網絡請求都是異步的,你不必擔心異步處理問題。Vo