編輯:Android開發實例
在工作中又很多需求都不是android系統自帶的控件可以達到效果的,內置的TabHost就是,只能達到簡單的效果 ,所以這個時候就要自定義控件來達到效果:這個效果就是: 使用自定義RadioButton和ViewPager實現TabHost帶滑動的頁卡效果。
這篇文章技術含量一般,大家別見笑。源碼我以測試,在底部可下載。
好了先上效果圖:
以下是實現步驟:
1、准備自定義RadioButton控件的樣式圖片等,就是准備配置文件:
(1)、 在項目的values文件夾裡面創建 attrs.xml :
代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyRadioButton">
<attr name="pic" format="reference" />
</declare-styleable>
</resources>
(2)、創建 styles.xml:
代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="radioButtonStyle">
<item name="android:button">@null</item>
<item name="android:textSize">12dip</item>
<item name="android:gravity">center_horizontal|bottom</item>
<item name="android:paddingBottom">5dip</item>
</style>
</resources>
(3)、把中文定義在string.xml裡:
代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, MainAct!</string>
<string name="app_name">TabHost</string>
<string name="home">大廳</string>
<string name="account">用戶</string>
<string name="beanExchange">玩具</string>
<string name="winAcciche">公告</string>
<string name="more">更多</string>
</resources>
(4)、創建MyRadioButton類繼承RadioButton:
代碼如下:
package com.dome.viewer.widget;
import com.dome.viewer.R;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable;
import android.util.AttributeSet;
import android.widget.RadioButton;
public class MyRadioButton extends RadioButton {
private Drawable drawable;
public MyRadioButton(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyRadioButton);
drawable = a.getDrawable(R.styleable.MyRadioButton_pic);
}
//Drawable轉換成Bitmap
private Bitmap drawable2Bitmap(Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
} else if (drawable instanceof NinePatchDrawable) {
Bitmap bitmap = Bitmap
.createBitmap(
drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight(),
drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
: Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
drawable.draw(canvas);
return bitmap;
} else {
return null;
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Bitmap image = drawable2Bitmap(drawable);
if (image != null) {
Paint pt = new Paint();
pt.setARGB(255, 66, 66, 66);
// 消除鋸齒
pt.setAntiAlias(true);
// 居中顯示圖片
int imageX = (int) (this.getWidth() - image.getWidth()) / 2;
canvas.drawBitmap(image, imageX, 2, pt);
pt.setARGB(255, 255, 255, 255);
}
}
}
(5)、為Activity准備布局文件,命名為:tabhost.xml:
代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:attrstest="http://schemas.android.com/apk/res/com.dome.viewer"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/bg" >
<RelativeLayout
android:id="@+id/title"
android:layout_width="fill_parent"
android:layout_height="50dip"
android:background="@drawable/bg_navigation" >
<TextView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerVertical="true"
android:layout_marginLeft="5dip"
android:gravity="center"
android:text="首頁"
android:textSize="25dip" />
</RelativeLayout>
<android.support.v4.view.ViewPager
android:id="@+id/vPager"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:paddingBottom="55dip"
android:persistentDrawingCache="animation" />
<RadioGroup
android:id="@+id/rg_main_btns"
android:layout_width="fill_parent"
android:layout_height="50dip"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom"
android:background="@drawable/bg_navigation"
android:gravity="center_horizontal"
android:orientation="horizontal" >
<com.dome.viewer.widget.MyRadioButton
android:id="@+id/buyHomeTab"
android:layout_width="60dip"
android:layout_height="50dip"
android:background="@drawable/navigation_item"
android:checked="true"
attrstest:pic="@drawable/gcdt"
android:text="@string/home" />
<com.dome.viewer.widget.MyRadioButton
android:id="@+id/winAfficheTab"
android:layout_width="60dip"
android:layout_height="50dip"
android:background="@drawable/navigation_item"
android:button="@null"
attrstest:pic="@drawable/kjgg"
android:text="@string/winAcciche" />
<com.dome.viewer.widget.MyRadioButton
android:id="@+id/integralTab"
android:layout_width="65dip"
android:layout_height="50dip"
android:background="@drawable/navigation_item"
attrstest:pic="@drawable/jfdh"
android:text="@string/beanExchange" />
<com.dome.viewer.widget.MyRadioButton
android:id="@+id/accountTab"
android:layout_width="60dip"
android:layout_height="50dip"
android:background="@drawable/navigation_item"
attrstest:pic="@drawable/yhzx"
android:text="@string/account" />
<com.dome.viewer.widget.MyRadioButton
android:id="@+id/moreTab"
android:layout_width="60dip"
android:layout_height="50dip"
android:background="@drawable/navigation_item"
attrstest:pic="@drawable/more"
android:text="@string/more" />
</RadioGroup>
</RelativeLayout>
(6)、創建TabHostActivity:
代碼如下:
package com.dome.viewer;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.app.LocalActivityManager;
import android.content.Intent;
import android.os.Bundle;
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.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.RadioGroup;
public class TabHostActivity extends Activity {
@Override
protected void onStart() {
super.onStart();
}
private RadioGroup radioGroup;
// 頁卡內容
private ViewPager mPager;
// Tab頁面列表
private List<View> listViews;
// 當前頁卡編號
private LocalActivityManager manager = null;
private MyPagerAdapter mpAdapter = null;
private int index;
// 更新intent傳過來的值
@Override
protected void onNewIntent(Intent intent) {
setIntent(intent);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
}
@Override
public void onBackPressed() {
Log.i("","onBackPressed()");
super.onBackPressed();
}
@Override
protected void onPause() {
Log.i("","onPause()");
super.onPause();
}
@Override
protected void onStop() {
Log.i("","onStop()");
super.onStop();
}
@Override
protected void onDestroy() {
Log.i("","onDestroy()");
super.onDestroy();
}
@Override
protected void onResume() {
super.onResume();
if(getIntent() != null){
index = getIntent().getIntExtra("index", 0);
mPager.setCurrentItem(index);
setIntent(null);
}else{
if(index < 4){
index = index+1;
mPager.setCurrentItem(index);
index = index -1;
mPager.setCurrentItem(index);
}else if(index == 4){
index= index-1;
mPager.setCurrentItem(index);
index = index +1;
mPager.setCurrentItem(index);
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.tabhost);
mPager = (ViewPager) findViewById(R.id.vPager);
manager = new LocalActivityManager(this, true);
manager.dispatchCreate(savedInstanceState);
InitViewPager();
radioGroup = (RadioGroup) this.findViewById(R.id.rg_main_btns);
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId) {
case R.id.buyHomeTab:
index = 0;
listViews.set(0, getView("A", new Intent(TabHostActivity.this, OneDomeActivity.class)));
mpAdapter.notifyDataSetChanged();
mPager.setCurrentItem(0);
break;
case R.id.winAfficheTab:
index = 1;
listViews.set(1, getView("B", new Intent(TabHostActivity.this, TowDomeActivity.class)));
mpAdapter.notifyDataSetChanged();
mPager.setCurrentItem(1);
break;
case R.id.integralTab:
index = 2;
listViews.set(2, getView("C", new Intent(TabHostActivity.this, ThreeDomeActivity.class)));
mpAdapter.notifyDataSetChanged();
mPager.setCurrentItem(2);
break;
case R.id.accountTab:
index = 3;
listViews.set(3, getView("D", new Intent(TabHostActivity.this, FourDomeActivity.class)));
mpAdapter.notifyDataSetChanged();
mPager.setCurrentItem(3);
break;
case R.id.moreTab:
index = 4;
listViews.set(4, getView("E", new Intent(TabHostActivity.this, FiveDomeActivity.class)));
mpAdapter.notifyDataSetChanged();
mPager.setCurrentItem(4);
break;
default:
break;
}
}
});
}
/**
* 初始化ViewPager
*/
private void InitViewPager() {
Intent intent = null;
listViews = new ArrayList<View>();
mpAdapter = new MyPagerAdapter(listViews);
intent = new Intent(TabHostActivity.this, OneDomeActivity.class);
listViews.add(getView("A", intent));
intent = new Intent(TabHostActivity.this, TowDomeActivity.class);
listViews.add(getView("B", intent));
intent = new Intent(TabHostActivity.this, ThreeDomeActivity.class);
listViews.add(getView("C", intent));
intent = new Intent(TabHostActivity.this, FourDomeActivity.class);
listViews.add(getView("D", intent));
intent = new Intent(TabHostActivity.this, FiveDomeActivity.class);
listViews.add(getView("E", intent));
mPager.setOffscreenPageLimit(0);
mPager.setAdapter(mpAdapter);
mPager.setCurrentItem(0);
mPager.setOnPageChangeListener(new MyOnPageChangeListener());
}
/**
* ViewPager適配器
*/
public class MyPagerAdapter extends PagerAdapter {
public List<View> mListViews;
public MyPagerAdapter(List<View> mListViews) {
this.mListViews = mListViews;
}
@Override
public void destroyItem(View arg0, int arg1, Object arg2) {
((ViewPager) arg0).removeView(mListViews.get(arg1));
}
@Override
public void finishUpdate(View arg0) {
}
@Override
public int getCount() {
return mListViews.size();
}
@Override
public Object instantiateItem(View arg0, int arg1) {
((ViewPager) arg0).addView(mListViews.get(arg1), 0);
return mListViews.get(arg1);
}
@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) {
}
}
/**
* 頁卡切換監聽,ViewPager改變同樣改變TabHost內容
*/
public class MyOnPageChangeListener implements OnPageChangeListener {
public void onPageSelected(int arg0) {
manager.dispatchResume();
switch (arg0) {
case 0:
index = 0;
radioGroup.check(R.id.buyHomeTab);
listViews.set(0, getView("A", new Intent(TabHostActivity.this, OneDomeActivity.class)));
mpAdapter.notifyDataSetChanged();
break;
case 1:
index = 1;
radioGroup.check(R.id.winAfficheTab);
listViews.set(1, getView("B", new Intent(TabHostActivity.this, TowDomeActivity.class)));
mpAdapter.notifyDataSetChanged();
break;
case 2:
index = 2;
radioGroup.check(R.id.integralTab);
listViews.set(2, getView("C", new Intent(TabHostActivity.this, ThreeDomeActivity.class)));
mpAdapter.notifyDataSetChanged();
break;
case 3:
index = 3;
radioGroup.check(R.id.accountTab);
listViews.set(3, getView("D", new Intent(TabHostActivity.this, FourDomeActivity.class)));
mpAdapter.notifyDataSetChanged();
break;
case 4:
index = 4;
radioGroup.check(R.id.moreTab);
listViews.set(4, getView("E", new Intent(TabHostActivity.this, FiveDomeActivity.class)));
mpAdapter.notifyDataSetChanged();
break;
}
}
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
public void onPageScrollStateChanged(int arg0) {
}
}
private View getView(String id, Intent intent) {
return manager.startActivity(id, intent).getDecorView();
}
}
(7)、然後依次創建5個Activity作為頁卡,和創建5個xml作為Activity的布局文件,如圖:
源碼下載
登錄應用程序的屏幕,詢問憑據登錄到一些特定的應用。可能需要登錄到Facebook,微博等本章介紹了,如何創建一個登錄界面,以及如何管理安全問題和錯誤嘗試。首先,必須定義兩
可以顯示在的Android任務,通過加載進度條的進展。進度條有兩種形狀。加載欄和加載微調(spinner)。在本章中,我們將討論微調(spinner)。Spinner 用
JSON代表JavaScript對象符號。它是一個獨立的數據交換格式,是XML的最佳替代品。本章介紹了如何解析JSON文件,並從中提取所需的信息。Android提供了四個
Android提供了許多方法來控制播放的音頻/視頻文件和流。其中該方法是通過一類稱為MediaPlayer。Android是提供MediaPlayer類訪問內置的媒體播放