1. 程式人生 > >安卓自定義view之打造滾動的通知欄

安卓自定義view之打造滾動的通知欄

閒談:

這段時間一直忙著做畢業設計,沒什麼時間寫blog,但是秉著分享的原則,還是要和小夥伴們分享所學的東西,如果可以的話,也希望我的部落格能夠幫助到需要的人。(打個廣告吧,有興趣的同學可以加一下我的安卓QQ群279031247,一起討論安卓開發遇到的問題)。

前言:

最近在開發一個app的時候,有個滾動通知欄的需求,自己花了一點時間去實現了一下,唯一可惜的事情就是自己沒有多少時間做成公開庫,希望有心的同學能夠封裝一下微笑。廢話不多說,開始我們今天的教程。

正文:

今天我們要實現的效果圖是這樣的。


我覺得這樣的需求,很多人都可能遇到這樣的吧,沒關係,實現這樣的效果還是比較簡單的,程式碼也是很少的。

專案結構圖:



學習這篇部落格之前,你得對重寫view、viewgroup有一定的認識,不清楚的話,可以看我之前寫的幾篇部落格。還要對ViewFlipper這個控制元件有點了解,我們的滾動效果就是基於這個實現的。大笑

由於通知條目有很多條,其實就是有個動態個數的TextvIew,左邊是一個ImageView,這個沒有什麼好多說的。我們來看看我們的自定義控制元件的佈局。

scrollnoticebar.xml:

<?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="horizontal" >

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginLeft="5.0dip"
        android:layout_marginTop="5.0dip"
        android:src="@drawable/volumn" />

    <ViewFlipper
        android:id="@+id/id_scrollNoticeTitle"
        android:layout_width="0dip"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_weight="1"
        android:layout_marginTop="3.0dip"
        android:flipInterval="5000"
        android:padding="5.0dip" >

        <TextView
            android:id="@+id/id_scrollNoticeContent1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="這是第一條通知內容....." />

        <TextView
            android:id="@+id/id_scrollNoticeContent2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="我就是一個非常喜歡程式設計的人......" />
    </ViewFlipper>

</LinearLayout>
我這邊先固定的顯示了兩條效果,在初始化自定義view 的時候,通過網路獲取顯示需要顯示的通知內容。這邊的flipInterval就是顯示的間隔時間。(沒有騙你們吧,確實佈局還是挺簡單的。)

重頭戲來了,是不是已經迫不及待了,對,我也是這樣的感覺。偷笑

PublicNoticeView.java:

package com.beyole.view;

import com.beyole.scrollnoticebar.R;

import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.AnimationUtils;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.ViewFlipper;

public class PublicNoticeView extends LinearLayout {

	private static final String TAG = "PUBLICNOTICEVIEW";
	private Context mContext;
	private ViewFlipper mViewFlipper;
	private View mScrollTitleView;

	public PublicNoticeView(Context context) {
		super(context);
		mContext = context;
		init();
	}

	public PublicNoticeView(Context context, AttributeSet attrs) {
		super(context, attrs);
		mContext = context;
		init();
	}

	private void init() {
		bindLinearLayout();
		bindNotices();
	}

	/**
	 * 初始化自定義的佈局
	 */
	private void bindLinearLayout() {
		mScrollTitleView = LayoutInflater.from(mContext).inflate(R.layout.scrollnoticebar, null);
		LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
		addView(mScrollTitleView, params);
		mViewFlipper = (ViewFlipper) mScrollTitleView.findViewById(R.id.id_scrollNoticeTitle);
		mViewFlipper.setInAnimation(AnimationUtils.loadAnimation(mContext, R.anim.slide_in_bottom));
		mViewFlipper.setOutAnimation(AnimationUtils.loadAnimation(mContext, R.anim.slide_out_top));
		mViewFlipper.startFlipping();
	}

	/**
	 * 網路請求內容後進行適配
	 */
	protected void bindNotices() {
		mViewFlipper.removeAllViews();
		int i = 0;
		while (i < 5) {
			String text = "公告:恭喜您中了500W,趕緊去領取吧!";
			TextView textView = new TextView(mContext);
			textView.setText(text);
			LayoutParams layoutParams = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
			mViewFlipper.addView(textView, layoutParams);
			i++;
		}
	}

}

我們這邊繼承的是LinearLayout,寫了兩個不同的構造方法,並在裡面初始化我們的元件。仔細思考一下,我們的初始化工作需要做哪些工作。毋庸置疑,第一個肯定是獲取我們的佈局,然後在我們的控制元件中addView到其中。那麼,第二步呢?可以說是獲取資料,但是我們先設定一下ViewFlipper的動畫效果。

接下來我們需要去獲取網路資訊,我這邊就直接迴圈了5條資料,然後在bindLinearLayout方法之後呼叫bindNotices方法。okay了,已經完成90%的工作了,就讓我們呼叫吧。

activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.beyole.view.PublicNoticeView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >
    </com.beyole.view.PublicNoticeView>

</RelativeLayout>

MainActivity.java:
package com.beyole.scrollnoticebar;

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {

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

}

這上面都沒什麼好說的,不懂的自己面壁去。

額,講到這裡忘記一件事,還有個動畫檔案沒有貼出來。

slide_in_bottom.xml:

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

    <translate
        android:duration="1000"
        android:fromYDelta="100%p"
        android:toYDelta="0" />

</set>

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

    <translate
        android:duration="1000"
        android:fromYDelta="0"
        android:toYDelta="-100%p" />

</set>
好好看上面的引數哦,不要看漏了符號。吐舌頭


雖然知道很少有人能夠看到這句話,還是要說一下,如果的部落格的幫助到了你,就留個言點個贊吧,可以的話,加一下我的安卓QQ群279031247。你們的鼓勵,是我分享更多程式碼的動力哦。