1. 程式人生 > >Android Tab 切換比較好的例子

Android Tab 切換比較好的例子

package com.aliyun.bluetoothphone.component;

import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;

import com.aliyun.bluetoothphone.R;
import com.aliyun.bluetoothphone.data.NameValueTable;
import com.aliyun.bluetoothphone.data.ProviderNameValueTable;
import com.aliyun.bluetoothphone.fragment.CalllogsFragment;
import com.aliyun.bluetoothphone.fragment.ContactsFragment;
import com.aliyun.bluetoothphone.fragment.DialpadFragment;
import com.aliyun.bluetoothphone.usertrack.UserTrackHelper;
import com.aliyun.bluetoothphone.util.Constants;
import com.aliyun.bluetoothphone.util.LogUtil;

public class BluetoothBaseActivity extends Activity implements OnClickListener {

    private static final String TAG = "BluetoothBaseActivity";

    private static final int FRAGMENT_ID_CALLLOGS = 0;
    private static final int FRAGMENT_ID_CONTACTS = 1;
    private static final int FRAGMENT_ID_DIAL = 2;

    private int currentFragmentId;
    private int tempFragmentId = -1;

    private Fragment fragmentCalllogs = null;
    private Fragment fragmentContacts = null;
    private Fragment fragmentDial = null;

    FrameLayout mFrameLayout;
    LinearLayout mLinearLayout;

    private ImageView mCalllogBtn;
    private ImageView mContactsBtn;
    private ImageView mDialBtn;

    private HfpManager hfpManager;

    private State state;

    private NameValueTable global;
    private NameValueTable local;
    private BroadcastReceiver stateReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            LogUtil.trace("stateReceiver: " + intent);

            if (intent == null) {
                return;
            }

            String action = intent.getAction();

            if (BluetoothProvider.LocalState.ACTION_BLUETOOTH_LOCAL_STATE_CHANGED.equals(action)
                    || BluetoothProvider.GlobalState.ACTION_BLUETOOTH_STATE_CHANGED.equals(action)) {
                refresh();
            }
            if(Constants.ACTION_BASEACTIVITY_FINISH.equals(action)){
                closeActivity();
            }
        }

    };

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

        ContactManager.getInstance();

        hfpManager = new HfpManager(getMainLooper());

        initView();

        if (savedInstanceState != null) {
            LogUtil.e(TAG, "savedInstanceState != null");
            currentFragmentId = savedInstanceState.getInt("currentFragmentId");
            fragmentCalllogs = getFragmentManager().findFragmentByTag("fragmentCalllogs");
            fragmentContacts = getFragmentManager().findFragmentByTag("fragmentContacts");
            fragmentDial = getFragmentManager().findFragmentByTag("fragmentDial");
        }

        LogUtil.trace();
        global = new ProviderNameValueTable(this, BluetoothProvider.GlobalState.CONTENT_URI,
                BluetoothProvider.GlobalState.COLUMN_NAME, BluetoothProvider.GlobalState.COLUMN_VALUE);
        local = new ProviderNameValueTable(this, BluetoothProvider.LocalState.CONTENT_URI,
                BluetoothProvider.LocalState.COLUMN_NAME, BluetoothProvider.LocalState.COLUMN_VALUE);
    }

    @Override
    protected void onResume() {
        super.onResume();
        LogUtil.trace();
        IntentFilter enableFilter = new IntentFilter();
        enableFilter.addAction(BluetoothProvider.LocalState.ACTION_BLUETOOTH_LOCAL_STATE_CHANGED);
        enableFilter.addAction(BluetoothProvider.GlobalState.ACTION_BLUETOOTH_STATE_CHANGED);
        enableFilter.addAction(Constants.ACTION_BASEACTIVITY_FINISH);
        registerReceiver(stateReceiver, enableFilter);
        refresh();
        checkCallStatus();
    }

    public State queryState() {
        if (global.getInt(BluetoothProvider.GlobalState.KEY_STATUS) != BluetoothProvider.GlobalState.STATUS_CONNECTED) {
            return State.NO_CONNECT;
        }

        if (local.getInt(
                BluetoothProvider.LocalState.KEY_SYNC_ENABLE) == BluetoothProvider.LocalState.VALUE_SWITCH_OFF) {
            return State.NO_CONNECT;
        }

        int status = local.getInt(BluetoothProvider.LocalState.KEY_SYNC_STATUS);
        switch (status) {
            case BluetoothProvider.LocalState.SYNC_STATUS_START:
            case BluetoothProvider.LocalState.SYNC_STATUS_PROCESSING_CONTACT:
                return State.PROCESS_CONTACT;
            case BluetoothProvider.LocalState.SYNC_STATUS_PROCESSING_CALL_RECORD:
                return State.PROCESS_CALL_RECORD;
            case BluetoothProvider.LocalState.SYNC_STATUS_COMPLETED:
                return State.COMPLETED;
            case BluetoothProvider.LocalState.SYNC_STATUS_ERROR:
                return State.ERROR;
            case BluetoothProvider.LocalState.SYNC_STATUS_NO_CONNECT:
            default:
                return State.NO_CONNECT;
        }
    }

    /**
     * check if current status is incoming/outgoing/callactive, if it is, then start talking activity
     */
    public void checkCallStatus() {
        if (hfpManager != null) {
            int status = hfpManager.queryHfpStatus();
            switch (status) {
                case HfpManager.HFP_STATUS_CALL_ACTIVE:
                case HfpManager.HFP_STATUS_INCOMING_CALL:
                case HfpManager.HFP_STATUS_OUTGOING_CALL:
                    sendStartTalkingBroadcast();
                   // this.finish();
                    break;
            }
        }

    }

    /**
     * notify bluetooth service, start talking activity
     */
    private void sendStartTalkingBroadcast() {
        Intent intent = new Intent(Constants.ACTION_STATUS_BAR_CLICK);
        sendBroadcast(intent);

    }

    @Override
    protected void onStart() {
        super.onStart();
        LogUtil.trace();
    }

    @Override
    protected void onPause() {
        LogUtil.trace();
        unregisterReceiver(stateReceiver);
        super.onPause();
    }

    @Override
    protected void onStop() {
        LogUtil.trace();
        super.onStop();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        outState.putInt("currentFragmentId", currentFragmentId);
        super.onSaveInstanceState(outState);
    }

    @Override
    protected void onDestroy() {
        LogUtil.trace();
        super.onDestroy();
    }

    private void initView() {
        mFrameLayout = (FrameLayout) findViewById(R.id.view_base_container);
        mLinearLayout = (LinearLayout) findViewById(R.id.linearlayout_base_prompt);

        mCalllogBtn = (ImageView) findViewById(R.id.btn_calllogs);
        mContactsBtn = (ImageView) findViewById(R.id.btn_contacts);
        mDialBtn = (ImageView) findViewById(R.id.btn_dialpad);

        mCalllogBtn.setTag(FRAGMENT_ID_CALLLOGS);
        mCalllogBtn.setOnClickListener(this);

        mContactsBtn.setTag(FRAGMENT_ID_CONTACTS);
        mContactsBtn.setOnClickListener(this);

        mDialBtn.setTag(FRAGMENT_ID_DIAL);
        mDialBtn.setOnClickListener(this);
    }
    
    private void closeActivity() {
        this.finish();        
    }
    
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_calllogs:
                currentFragmentId = FRAGMENT_ID_CALLLOGS;
                UserTrackHelper.ctrlClicked(BluetoothBaseActivity.class, UserTrackHelper.CLICK_BTN_CALLLOGS);
                break;
            case R.id.btn_contacts:
                currentFragmentId = FRAGMENT_ID_CONTACTS;
                UserTrackHelper.ctrlClicked(BluetoothBaseActivity.class, UserTrackHelper.CLICK_BTN_CONTACTS);
                break;
            case R.id.btn_dialpad:
                currentFragmentId = FRAGMENT_ID_DIAL;
                UserTrackHelper.ctrlClicked(BluetoothBaseActivity.class, UserTrackHelper.CLICK_BTN_DIALPAD);
                break;

            default:
                break;
        }
        updateUI();
    }

    private void usetrackChange(int PageEnter, int PageLeave) {
        LogUtil.e(TAG, "PageEnter = " + PageEnter + ", PageLeave = " + PageLeave);
        if (PageEnter == PageLeave)
            return;
        switch (PageLeave) {
            case FRAGMENT_ID_CALLLOGS:
                UserTrackHelper.pageLeave(UserTrackHelper.PAGE_CALLLOGS);
                break;
            case FRAGMENT_ID_CONTACTS:
                UserTrackHelper.pageLeave(UserTrackHelper.PAGE_CONTACTS);
                break;
            case FRAGMENT_ID_DIAL:
                UserTrackHelper.pageLeave(UserTrackHelper.PAGE_DIALPAD);
                break;

            default:
                break;
        }

        switch (PageEnter) {
            case FRAGMENT_ID_CALLLOGS:
                UserTrackHelper.pageEnter(UserTrackHelper.PAGE_CALLLOGS);
                break;
            case FRAGMENT_ID_CONTACTS:
                UserTrackHelper.pageEnter(UserTrackHelper.PAGE_CONTACTS);
                break;
            case FRAGMENT_ID_DIAL:
                UserTrackHelper.pageEnter(UserTrackHelper.PAGE_DIALPAD);
                break;

            default:
                break;
        }
    }

    private void replaceFragment(int fragmentId) {
        currentFragmentId = fragmentId;
        FragmentTransaction transaction = getFragmentManager().beginTransaction();

        if (tempFragmentId < fragmentId) {
            transaction.setCustomAnimations(R.animator.fragment_slide_up_enter, R.animator.fragment_slide_up_exit);
        } else if (tempFragmentId > fragmentId) {
            transaction.setCustomAnimations(R.animator.fragment_slide_down_enter, R.animator.fragment_slide_down_exit);
        }

        hideFragments(transaction);

        if (tempFragmentId < fragmentId) {
            transaction.setCustomAnimations(R.animator.fragment_slide_up_enter, R.animator.fragment_slide_up_exit);
        } else if (tempFragmentId > fragmentId) {
            transaction.setCustomAnimations(R.animator.fragment_slide_down_enter, R.animator.fragment_slide_down_exit);
        }

        usetrackChange(fragmentId, tempFragmentId);
        tempFragmentId = fragmentId;

        switch (fragmentId) {
            case FRAGMENT_ID_CALLLOGS:
                if (fragmentCalllogs != null) {
                    transaction.show(fragmentCalllogs);
                } else {
                    fragmentCalllogs = new CalllogsFragment(hfpManager);
                    transaction.add(R.id.view_base_container, fragmentCalllogs, "fragmentCalllogs");
                }
                break;
            case FRAGMENT_ID_CONTACTS:
                if (fragmentContacts != null) {
                    transaction.show(fragmentContacts);
                } else {
                    fragmentContacts = new ContactsFragment(hfpManager);
                    transaction.add(R.id.view_base_container, fragmentContacts, "fragmentContacts");
                }
                break;
            case FRAGMENT_ID_DIAL:
                if (fragmentDial != null) {
                    transaction.show(fragmentDial);
                } else {
                    fragmentDial = new DialpadFragment(hfpManager);
                    transaction.add(R.id.view_base_container, fragmentDial, "fragmentDial");
                }
                break;

            default:
                break;
        }

        transaction.commitAllowingStateLoss();
        updateSelected(fragmentId);
    }

    private void hideFragments(FragmentTransaction ft) {
        if (fragmentCalllogs != null)
            ft.hide(fragmentCalllogs);
        if (fragmentContacts != null)
            ft.hide(fragmentContacts);
        if (fragmentDial != null)
            ft.hide(fragmentDial);
    }

    private void updateSelected(int select) {
        switch (select) {
            case FRAGMENT_ID_CALLLOGS:
                mCalllogBtn.setImageResource(R.drawable.btn_call_logs_p);
                mContactsBtn.setImageResource(R.drawable.btn_contacts);
                mDialBtn.setImageResource(R.drawable.btn_dialpad);
                break;
            case FRAGMENT_ID_CONTACTS:
                mCalllogBtn.setImageResource(R.drawable.btn_call_logs);
                mContactsBtn.setImageResource(R.drawable.btn_contacts_p);
                mDialBtn.setImageResource(R.drawable.btn_dialpad);
                break;
            case FRAGMENT_ID_DIAL:
                mCalllogBtn.setImageResource(R.drawable.btn_call_logs);
                mContactsBtn.setImageResource(R.drawable.btn_contacts);
                mDialBtn.setImageResource(R.drawable.btn_dialpad_p);
                break;
            default:
                mCalllogBtn.setImageResource(R.drawable.btn_call_logs);
                mContactsBtn.setImageResource(R.drawable.btn_contacts);
                mDialBtn.setImageResource(R.drawable.btn_dialpad);
                break;
        }
    }

    private void refresh() {
        state = queryState();
        updateUI();
        switch (state) {
            case NO_CONNECT:
                break;
            case PROCESS_CONTACT: {
                int successCount = local.getInt(BluetoothProvider.LocalState.KEY_SUCCESS_COUNT, 0);
                int failedCount = local.getInt(BluetoothProvider.LocalState.KEY_FAILED_COUNT, 0);
                int totalCount = local.getInt(BluetoothProvider.LocalState.KEY_TOTAL_COUNT, -1);
                if (fragmentContacts != null) {
                    ContactsFragment contactsFragment = (ContactsFragment) fragmentContacts;
                    int type = local.getInt(BluetoothProvider.LocalState.KEY_SYNC_TYPE);
                    if (type == BluetoothProvider.LocalState.SYNC_TYPE_NEW_DEVICE) {
                        contactsFragment.setSyncing();
                        contactsFragment.setSyncProgress(successCount, failedCount, totalCount);
                    } else {
                        contactsFragment.setSynced(true);
                    }
                }
                if (fragmentCalllogs != null) {
                    CalllogsFragment calllogsFragment = (CalllogsFragment) fragmentCalllogs;
                    calllogsFragment.setSyncing();
                    calllogsFragment.setSyncProgress(0, 0, 0);
                }
                break;
            }
            case PROCESS_CALL_RECORD: {
                if (fragmentContacts != null) {
                    ContactsFragment contactsFragment = (ContactsFragment) fragmentContacts;
                    contactsFragment.setSynced(false);
                }
                if (fragmentCalllogs != null) {
                    CalllogsFragment calllogsFragment = (CalllogsFragment) fragmentCalllogs;
                    calllogsFragment.setSyncing();
                    calllogsFragment.setSyncProgress(0, 0, 0);
                }
                break;
            }
            case COMPLETED:
            case ERROR: {
                if (fragmentCalllogs != null) {
                    CalllogsFragment calllogsFragment = (CalllogsFragment) fragmentCalllogs;
                    calllogsFragment.setSynced();
                }
                break;
            }
        }
    }

    private void updateUI() {
        LogUtil.trace("state = " + state);

        if (currentFragmentId == FRAGMENT_ID_DIAL) {
            mFrameLayout.setVisibility(View.VISIBLE);
            mLinearLayout.setVisibility(View.GONE);
            replaceFragment(currentFragmentId);
            return;
        }

        if (state != State.NO_CONNECT) {
            mFrameLayout.setVisibility(View.VISIBLE);
            mLinearLayout.setVisibility(View.GONE);
            replaceFragment(currentFragmentId);
        } else {
            updateSelected(-1);
            mFrameLayout.setVisibility(View.GONE);
            mLinearLayout.setVisibility(View.VISIBLE);
        }
    }

    public boolean isHfpConnected() {
        return state != State.NO_CONNECT;
    }

    public HfpManager getHfpManager() {
        return hfpManager;
    }

    public static enum State {
        NO_CONNECT, PROCESS_CONTACT, PROCESS_CALL_RECORD, COMPLETED, ERROR
    }
}

xml檔案

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/base_activity"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/base_activity_bg"
    tools:context="com.zebra.alibluetooth.BluetoothBaseActivity" >

    <LinearLayout
        android:id="@+id/view_base_left"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:background="@color/board_bg"
        android:orientation="vertical" >

        <ImageButton
            android:id="@+id/btn_calllogs"
            android:layout_width="120dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_weight="1"
            android:background="@drawable/btn_background"
            android:scaleType="center"
            android:src="@drawable/btn_call_logs" />

        <ImageButton
            android:id="@+id/btn_contacts"
            android:layout_width="120dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_weight="1"
            android:background="@drawable/btn_background"
            android:src="@drawable/btn_contacts" />

        <ImageButton
            android:id="@+id/btn_dialpad"
            android:layout_width="120dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_weight="1"
            android:background="@drawable/btn_background"
            android:src="@drawable/btn_dialpad" />
    </LinearLayout>

    <FrameLayout
        android:id="@+id/view_base_container"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_alignParentRight="true"
        android:layout_toRightOf="@id/view_base_left" >
    </FrameLayout>

    <LinearLayout
        android:id="@+id/linearlayout_base_prompt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:orientation="horizontal"
        android:visibility="gone" >

        <ImageView
            android:id="@+id/imgview_base_prompt"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_margin="15dp"
            android:layout_weight="1"
            android:src="@drawable/icon_bt_bluetooth" />

        <TextView
            android:id="@+id/textview_base_prompt"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_margin="15dp"
            android:layout_weight="1"
            android:text="@string/base_noconnected"
            android:textColor="@color/white"
            android:textSize="25sp" />
    </LinearLayout>

</RelativeLayout>