編輯:關於Android編程
(項目中需要實現圖片輪番效果,就查資料著重學習,本地圖片實現)
原理就是利用定時任務器定時切換ViewPager的頁面,根據圖片個數動態生成下端的圓點。
效果圖:
1、獲取本地圖片實現輪番效果
布局:兩部分組成,viewpager和下端圓點的布局
<framelayout android:id="@+id/ui_home_autoImage" android:layout_height="200dp" android:layout_width="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"></framelayout>
主要代碼:定時任務,實現PagerAdapter
package com.xinyuan.cycleimage; import java.lang.ref.SoftReference; import java.util.ArrayList; import java.util.List; import android.annotation.TargetApi; import android.app.Activity; import android.app.ActionBar.LayoutParams; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.Parcelable; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager.OnPageChangeListener; import android.view.View; import android.view.ViewGroup; import android.view.ViewParent; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ImageView.ScaleType; /** * 輪番展示圖片 * @創建時間 :2016-1-6 * */ public class MainActivity extends Activity { private ViewPager viewPager; private ListimageViews; // 滑動的圖片集合 private int[] imageResId; // 圖片ID // 圓點圖片集合 private ImageView[] tips; private int currentItem = 0; // 當前圖片的索引號 private String[] defaultLength; private ImageHandler handler = new ImageHandler( new SoftReference (this)); // 切換當前顯示的圖片 private static class ImageHandler extends Handler { /** * 請求更新顯示的View。 */ protected static final int MSG_START_IMAGE = 0; /** * 請求更新顯示的View。 */ protected static final int MSG_UPDATE_IMAGE = 1; /** * 請求暫停輪播。 */ protected static final int MSG_KEEP_SILENT = 2; /** * 請求恢復輪播。 */ protected static final int MSG_BREAK_SILENT = 3; /** * 記錄最新的頁號,當用戶手動滑動時需要記錄新頁號,否則會使輪播的頁面出錯。 * 例如當前如果在第一頁,本來准備播放的是第二頁,而這時候用戶滑動到了末頁, * 則應該播放的是第一頁,如果繼續按照原來的第二頁播放,則邏輯上有問題。 */ protected static final int MSG_PAGE_CHANGED = 4; // 輪播間隔時間 protected static final long MSG_DELAY = 2000; // 使用弱引用避免Handler洩露.這裡的泛型參數可以不是Activity,也可以是Fragment等 private SoftReference weakReference; private int currentItem = 0; protected ImageHandler(SoftReference wk) { weakReference = wk; } @Override public void handleMessage(Message msg) { super.handleMessage(msg); MainActivity activity = weakReference.get(); if (activity == null) { // Activity已經回收,無需再處理UI了 return; } // 檢查消息隊列並移除未發送的消息,這主要是避免在復雜環境下消息出現重復等問題。 if (activity.handler.hasMessages(MSG_UPDATE_IMAGE)) { activity.handler.removeMessages(MSG_UPDATE_IMAGE); } switch (msg.what) { case MSG_UPDATE_IMAGE: currentItem++; activity.viewPager.setCurrentItem(currentItem); // 准備下次播放 activity.handler.sendEmptyMessageDelayed(MSG_UPDATE_IMAGE, MSG_DELAY); break; case MSG_START_IMAGE: currentItem++; activity.viewPager.setCurrentItem(currentItem); break; case MSG_KEEP_SILENT: // 只要不發送消息就暫停了 break; case MSG_BREAK_SILENT: activity.handler.sendEmptyMessageDelayed(MSG_UPDATE_IMAGE, MSG_DELAY); break; case MSG_PAGE_CHANGED: // 記錄當前的頁號,避免播放的時候頁面顯示不正確。 currentItem = msg.arg1; break; } } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); auto_Image(); } /** * 圖片輪番展示 * * @創建日期 2016-1-17 * * @返回值 void * */ private void auto_Image() { imageViews = new ArrayList (); imageResId = new int[] { R.drawable.banner01, R.drawable.banner02, R.drawable.banner01, R.drawable.banner02 }; for (int i = 0; i < imageResId.length; i++) { ImageView imageView = new ImageView(this); imageView.setImageResource(imageResId[i]); imageView.setScaleType(ScaleType.CENTER_CROP); imageViews.add(imageView); } defaultLength = new String[imageViews.size()]; dynamicAddition(defaultLength); viewPager = (ViewPager) findViewById(R.id.img_vp); viewPager.setAdapter(new MyAdapter());// 設置填充ViewPager頁面的適配器 // 設置一個監聽器,當ViewPager中的頁面改變時調用 viewPager.setOnPageChangeListener(new MyPageChangeListener()); currentItem = imageViews.size() * 100; viewPager.setCurrentItem(currentItem); // 開始輪播效果 handler.sendEmptyMessageDelayed(ImageHandler.MSG_START_IMAGE, ImageHandler.MSG_DELAY); } /** * 設置底部圓點滾動 * * @創建日期 2016-1-18 * * @參數 lengthCum 圖片個數 * @返回值 void * */ @TargetApi(Build.VERSION_CODES.HONEYCOMB) private void dynamicAddition(String[] lengthCum) { // 動態的添加圓點圖片設置 ViewGroup group = (ViewGroup) findViewById(R.id.viewGroup); tips = new ImageView[lengthCum.length]; for (int i = 0; i < tips.length; i++) { ImageView imageView = new ImageView(this); imageView.setScaleType(ImageView.ScaleType.FIT_XY); imageView.setLayoutParams(new LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); tips[i] = imageView; if (i == 0) { tips[i].setBackgroundResource(R.drawable.page_indicator_focused); } else { tips[i].setBackgroundResource(R.drawable.page_indicator_unfocused); } LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); layoutParams.leftMargin = 5; layoutParams.rightMargin = 5; group.addView(imageView, layoutParams); } } /** * 填充ViewPager頁面的適配器 * * @author Administrator * */ private class MyAdapter extends PagerAdapter { @Override public int getCount() { return Integer.MAX_VALUE; } @Override public Object instantiateItem(ViewGroup container, int position) { position = position % imageViews.size(); if (position < 0) { position = imageViews.size() + position; } ImageView view = imageViews.get(position); // 如果View已經在之前添加到了一個父組件,則必須先remove,否則會拋出IllegalStateException。 ViewParent vp = view.getParent(); if (vp != null) { ViewGroup parent = (ViewGroup) vp; parent.removeView(view); } container.addView(view); return view; } @Override public void destroyItem(View arg0, int arg1, Object arg2) { // ((ViewPager) arg0).removeView(imageViews.get(arg1%imageViews.size())); } @Override public boolean isViewFromObject(View arg0, Object arg1) { return arg0 == arg1; } @Override public void restoreState(Parcelable arg0, ClassLoader arg1) { } @Override public Parcelable saveState() { return null; } @Override public void startUpdate(View arg0) { } @Override public void finishUpdate(View arg0) { } } /** * 當ViewPager中頁面的狀態發生改變時調用 * * @author Administrator * */ private class MyPageChangeListener implements OnPageChangeListener { private int oldPosition = 0; public void onPageSelected(int position) { int p = position % imageViews.size(); currentItem = p; tips[oldPosition] .setBackgroundResource(R.drawable.page_indicator_unfocused); tips[p].setBackgroundResource(R.drawable.page_indicator_focused); oldPosition = p; handler.sendMessage(Message.obtain(handler, ImageHandler.MSG_PAGE_CHANGED, position, 0)); } // 覆寫該方法實現輪播效果的暫停和恢復 @Override public void onPageScrollStateChanged(int arg0) { switch (arg0) { case ViewPager.SCROLL_STATE_DRAGGING: handler.sendEmptyMessage(ImageHandler.MSG_KEEP_SILENT); break; case ViewPager.SCROLL_STATE_IDLE: handler.sendEmptyMessageDelayed(ImageHandler.MSG_UPDATE_IMAGE, ImageHandler.MSG_DELAY); break; default: break; } } public void onPageScrolled(int arg0, float arg1, int arg2) { } } }
注意:在實現PagerAdapter適配器時需要注意,在instantiateItem方法中,需要獲取view.getParent(),如果存在就移除,不需要在destroyItem方法中移除,否則會報下面的錯誤
前言:俗話說磨刀不誤砍柴工,一個優秀的產品從一個不錯的點子直到用戶的手中,是需要一個團隊不遺余力協同合作不斷打磨出來的;同樣,一個好的App除正常的代碼編寫外,還需要經過
1 基於Socket的Android聊天室Socket通信是網絡通信中最常用的技術之一,通過Socket建立的可靠連接,可以讓多個終端與服務器保持通信,最典型的應用是建立
RecyclerView出現已經有一段時間了,相信大家肯定不陌生了,大家可以通過導入support-v7對其進行使用。 據官方的介紹,該控件用於在有限的窗口中展示大量數據
最近看到一些應用在下載文件的時候,並沒有額外彈出進度條,而是很炫的使用啟動下載任務的Button直接顯示文件的下載進度,通過改變其背景色,從左向右推進,直到填滿整個But