標籤:android style blog http io ar color os 使用
為了實現廣告輪播功能,在網上找了很多方法,有的效果很好,但是代碼太麻煩,並且大多是用的viewpager,總之不是很滿意。
於是看了一下sdk有個控制項是ViewFlipper,使用比較方便,於是嘗試了一下,最終實現了所需效果。在這裡與大家分享。
首先看一下效果(主要是布局方面的效果,畢竟手勢識別和滑動不太好顯示,懶得弄成gif了):
1、布局檔案.xml
<LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android"> <ViewFlipper android:layout_width="fill_parent" android:layout_height="120dp" android:id="@+id/details" > </ViewFlipper> <RelativeLayout android:layout_width="fill_parent" android:layout_height="16dp" > <LinearLayout android:layout_width="fill_parent" android:layout_height="16dp" android:orientation="horizontal" android:gravity="right" > <View android:id="@+id/v_dot0" style="@style/dot_style" android:background="@drawable/dot_focused" /> <View android:id="@+id/v_dot1" style="@style/dot_style" /> <View android:id="@+id/v_dot2" style="@style/dot_style" /> </LinearLayout> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="left" android:text="hello" /> </RelativeLayout> </LinearLayout>
我來解釋一下這個布局
首先,最外層是一個LinearLayout布局來填充整個螢幕。
第二層就是控制項ViewFlipper與RelativeLayout並列。其中ViewFlipper是實現圖片輪播的,RelationLayout是圖片下面的資訊,比片的標題(中的&&)和圖片在所有圖片中的位置(表現形式為最右邊的白色小點)
第三層其實就是把第二層的RelativeLayout展開,裡面有一個TextView控制項來顯示標題,和三個View控制項來顯示小點。
下面是要用到的一些style和drawable代碼(該部分代碼來自網路):
前5個放在res/drawable檔案夾下
1、btn_back_selector.xml
<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/btn_top_pressed" android:state_focused="true"></item> <item android:drawable="@drawable/btn_top_pressed" android:state_pressed="true"></item> <item android:drawable="@drawable/btn_top_pressed" android:state_selected="true"></item> <item android:drawable="@drawable/title_bk"></item></selector>
2、btn_top_pressed.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="#009ad6" android:startColor="#11264f" /></shape>
3、dot_focused.xml
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" > <solid android:color="#aaFFFFFF" /> <corners android:radius="5dip" /></shape>
4、dot_normal.xml
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" > <solid android:color="#33000000" /> <corners android:radius="5dip" /></shape>
5、title_bk.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="#11264f" android:startColor="#009ad6" /></shape>
6、styles.xml(放在values檔案夾之下)
<?xml version="1.0" encoding="utf-8"?><resources> <style name="dot_style"> <item name="android:layout_width">5dip</item> <item name="android:layout_height">5dip</item> <item name="android:background">@drawable/dot_normal</item> <item name="android:layout_marginLeft">1.5dip</item> <item name="android:layout_marginRight">1.5dip</item> </style></resources>
這上面的代碼我也不怎麼懂,但是目的就是為了操作那些小點點。
下面問題來了,java代碼呢。不要急,這就上來。
下面高能,膽小誤入。
java代碼(先全都發上來,容我慢慢解釋)
package com.example.mynews;import java.util.ArrayList;import java.util.List;import android.annotation.SuppressLint;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.view.View.OnTouchListener;import android.view.ViewGroup.LayoutParams;import android.widget.ImageView;import android.widget.ImageView.ScaleType;import android.widget.TextView;import android.widget.Toast;import android.widget.ViewFlipper;public class MainActivity extends Activity{private ViewFlipper viewFlipper;private String[] titles;private TextView tv_title;private List<View> dots;float startx;float x = 0;float y = 0;@Override@SuppressWarnings("deprecation")protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);viewFlipper = (ViewFlipper)findViewById(R.id.details);tv_title = (TextView)findViewById(R.id.title);int image[] = new int[]{R.drawable.a,R.drawable.b,R.drawable.c};for(int i=0;i<image.length;i++){ ImageView iv = new ImageView(getApplicationContext());iv.setBackgroundResource(image[i]);iv.setScaleType(ScaleType.CENTER_INSIDE);iv.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));viewFlipper.addView(iv);}titles = new String[image.length];titles[0] = "hello";titles[1] = "&&";titles[2] = "world";dots = new ArrayList<View>();dots.add(findViewById(R.id.v_dot0));dots.add(findViewById(R.id.v_dot1));dots.add(findViewById(R.id.v_dot2));handler.sendMessageDelayed(new Message(), 5000);viewFlipper.setOnTouchListener(new OnTouchListener() { @SuppressLint("ClickableViewAccessibility")@Overridepublic boolean onTouch(View v, MotionEvent event) {// TODO Auto-generated method stubswitch(event.getAction()){case MotionEvent.ACTION_DOWN:{x = event.getX();Toast.makeText(getApplicationContext(), "down"+event.getX(), 1).show();}break;case MotionEvent.ACTION_UP:{y = event.getX();if(y>x){Log.v(null, "result:y>x");showPre();}else if(x==y){Log.v(null, "result:y=x");showDetail();}else{Log.v(null, "result:x>y");showNext();}}break;}return true;}});}private Handler handler = new Handler(){@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);showNext();handler.sendMessageDelayed(new Message(), 5000);} };private void showNext(){viewFlipper.showNext();int cur = viewFlipper.getDisplayedChild();if(cur == 0){dots.get(2).setBackgroundResource(R.drawable.dot_normal);}else{dots.get(cur-1).setBackgroundResource(R.drawable.dot_normal);}dots.get(cur).setBackgroundResource(R.drawable.dot_focused);tv_title.setText(titles[cur]);}private void showPre(){viewFlipper.showPrevious();int cur = viewFlipper.getDisplayedChild();if(cur == 2){dots.get(0).setBackgroundResource(R.drawable.dot_normal);}else{dots.get(cur+1).setBackgroundResource(R.drawable.dot_normal);}dots.get(cur).setBackgroundResource(R.drawable.dot_focused);tv_title.setText(titles[cur]);}private void showDetail(){Toast.makeText(getApplicationContext(),"x=y", 1).show();}}
1、先準備圖片,這裡我準備了三張,初始化代碼如下:
int image[] = new int[]//用int型數組來儲存三張照片的編號{R.drawable.a,R.drawable.b,R.drawable.c};for(int i=0;i<image.length;i++)//將三張照片加入viewflipper裡{ ImageView iv = new ImageView(getApplicationContext());iv.setBackgroundResource(image[i]);iv.setScaleType(ScaleType.CENTER_INSIDE);//這裡設定圖片變換格式iv.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));viewFlipper.addView(iv);}
2、對ViewFlipper設定監聽事件(進行手勢操作的核心),注意,這裡的監聽不是onclicklistener,而是ontouchlistener
viewFlipper.setOnTouchListener(new OnTouchListener() { @SuppressLint("ClickableViewAccessibility")@Overridepublic boolean onTouch(View v, MotionEvent event) {// TODO Auto-generated method stubswitch(event.getAction()){case MotionEvent.ACTION_DOWN://手指按下{x = event.getX();//全域變數,接收按下是的手指座標Toast.makeText(getApplicationContext(), "down"+event.getX(), 1).show();}break;case MotionEvent.ACTION_UP://手指鬆開{y = event.getX();//全域變數,接收鬆開是的手指座標//下面就是簡單的邏輯判斷,從而區分向左滑、向右滑以及不滑(也就是點擊事件)if(y>x){Log.v(null, "result:y>x");showPre();}else if(x==y){Log.v(null, "result:y=x");showDetail();}else{Log.v(null, "result:x>y");showNext();}}break;}return true;}});
這裡要重點說下,本來我採用的不是這種方法,而是將activity使用ontouch介面、ViewFlipper使用onclicklistener,而且還要聲明一個gesturedetector變數,這樣會出現一個問題,就是ontouch與onclick的事件會相互影響,具體怎麼回事,我也沒搞明白。有事件會仔細研究研究。此外,如果使用gesturedetector又會增加複雜度。
然後是圖片切換動作,也就是上段代碼中的showPre()、showNext()、showDetail()方法。作用分別是向左滑、向右滑、不滑(這裡可以用來實現點擊事件)代碼如下:
private void showNext(){viewFlipper.showNext();//sdk封裝好的,使用非常方便int cur = viewFlipper.getDisplayedChild();if(cur == 0){dots.get(2).setBackgroundResource(R.drawable.dot_normal);//這是控制那些小點點的,邏輯應該能看懂,就不解釋了}else{dots.get(cur-1).setBackgroundResource(R.drawable.dot_normal);}dots.get(cur).setBackgroundResource(R.drawable.dot_focused);tv_title.setText(titles[cur]);}private void showPre(){viewFlipper.showPrevious();//sdk封裝好的,使用非常方便int cur = viewFlipper.getDisplayedChild();if(cur == 2){dots.get(0).setBackgroundResource(R.drawable.dot_normal);}else{dots.get(cur+1).setBackgroundResource(R.drawable.dot_normal);}dots.get(cur).setBackgroundResource(R.drawable.dot_focused);tv_title.setText(titles[cur]);}private void showDetail(){Toast.makeText(getApplicationContext(),"x=y", 1).show();}
下面又到了另外一個重點,handler機制,其實和定時器差不多(至少在這裡是)
handler.sendMessageDelayed(new Message(), 5000);
沒5000ms也就是5s發送一次訊息,這個訊息是幹嘛的?請看下端代碼
private Handler handler = new Handler(){@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);showNext();handler.sendMessageDelayed(new Message(), 5000);} };
簡單的講,它是給他自己發訊息,提醒自己時間到了,該吃藥了(該做某件事了)。然後做完之後還要告訴自己,過5s還要吃藥,就這樣一直吃藥,不放棄治療。
我想,說到這裡,應該明白,這段代碼的功能就是實現圖片的自動切換。
至此,代碼的重點部分解釋完了。至於標題和那些小點點怎麼處理,都在那三個方法裡寫好了,肯定可以看明白,就不多贅述了。
附:
1、代碼出問題盡量不要找我,雖然是我寫的,但是它自己長歪了。
2、轉載請註明出處。
謝謝閱讀,歡迎批評指正。
Android 通過ViewFlipper實現廣告輪播功能並可以通過手勢滑動進行廣告切換