編輯:Android開發實例
在前面幾講中,左側菜單(左側面板)、滿足滑動或點擊子View的方式,打開左側菜單的父容器和新鮮事視圖(雛形)已基本完成,這一篇我們將主界面的整個視圖框架完善下,實現點擊左側菜單切換右側視圖的功能。
一、添加消息中心視圖
通過觀察,發現消息中心與新鮮事視圖的頂部導航欄(工具欄)非常類似,既然類似就自定義組件,在兩個視圖需要用到的位置包含進去就可以了,降低代碼冗余度。
頂部導航欄的布局文件(top_menu_navbar.xml):
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" >
- <LinearLayout
- android:id="@+id/ll_back"
- android:layout_width="60dip"
- android:layout_height="fill_parent"
- android:background="@drawable/v5_0_1_flipper_head_title_wrapper_background"
- android:gravity="center_vertical" >
- <ImageView
- android:id="@+id/iv_back"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginLeft="15dip"
- android:src="@drawable/v5_0_1_flipper_head_flip" />
- </LinearLayout>
- <ImageView
- android:id="@+id/iv_line_separator"
- android:layout_width="1dip"
- android:layout_height="25dip"
- android:layout_centerVertical="true"
- android:layout_toRightOf="@+id/ll_back"
- android:background="@drawable/v5_0_1_flipper_head_separator" />
- <LinearLayout
- android:id="@+id/ll_down_list"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:layout_marginLeft="5dip"
- android:layout_toRightOf="@+id/iv_line_separator"
- android:background="@drawable/v5_0_1_flipper_head_title_wrapper_background" >
- <TextView
- android:id="@+id/tv_title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:layout_marginLeft="5dip"
- android:text="新鮮事"
- android:textColor="#FFFFFF"
- android:textSize="17dip"
- android:textStyle="bold" />
- <ImageView
- android:id="@+id/iv_down_list_icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom"
- android:layout_marginBottom="3dip"
- android:layout_marginLeft="5dip"
- android:layout_marginRight="5dip"
- android:src="@drawable/v5_0_1_flipper_head_title_corner" />
- </LinearLayout>
- <ImageView
- android:id="@+id/iv_right_line"
- android:layout_width="1dip"
- android:layout_height="25dip"
- android:layout_centerVertical="true"
- android:layout_toLeftOf="@+id/ll_refresh"
- android:background="@drawable/v5_0_1_flipper_head_separator" />
- <LinearLayout
- android:id="@+id/ll_refresh"
- android:layout_width="60dip"
- android:layout_height="fill_parent"
- android:layout_alignParentRight="true"
- android:background="@drawable/v5_0_1_flipper_head_title_wrapper_background"
- android:gravity="center" >
- <TextView
- android:id="@+id/tv_right_operation_name"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:layout_marginLeft="5dip"
- android:text="編輯"
- android:textColor="#FFFFFF"
- android:textSize="17dip"
- android:textStyle="bold" />
- <ImageView
- android:id="@+id/iv_refresh"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/refresh_icon" />
- </LinearLayout>
- </RelativeLayout>
頂部導航欄的Java文件:
- package com.everyone.android.widget;
- import android.content.Context;
- import android.util.AttributeSet;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.widget.FrameLayout;
- import android.widget.ImageView;
- import android.widget.LinearLayout;
- import android.widget.RelativeLayout;
- import android.widget.TextView;
- import com.everyone.android.R;
- import com.everyone.android.api.OnMenuClickListener;
- /**
- * 功能描述:自定義頂部菜單欄
- * @author android_ls
- */
- public class TopMenuNavbar extends FrameLayout {
- // 打開左側菜單的組件
- private LinearLayout llShowMenu;
- /**
- * 下拉列表
- */
- public LinearLayout mLlDownList;
- /**
- * 當前的標題
- */
- public TextView tvTitle;
- /**
- * 下拉標識
- */
- public ImageView ivDownListIcon;
- /**
- * 刷新圖標
- */
- public ImageView ivRefresh;
- /**
- * 右側操作(動作)的名稱
- */
- public TextView tvRightOperationName;
- /**
- * 右側豎直分割線
- */
- public ImageView ivRightLine;
- /**
- * 右側的操作觸控組件
- */
- public LinearLayout mLlRefresh;
- /**
- * 打開左側菜單的組件的事件監聽器
- */
- private OnMenuClickListener mOnClickListener;
- public TopMenuNavbar(Context context) {
- super(context);
- setupViews();
- }
- public TopMenuNavbar(Context context, AttributeSet attrs) {
- super(context, attrs);
- setupViews();
- }
- public void setOnClickListener(OnMenuClickListener onClickListener) {
- mOnClickListener = onClickListener;
- }
- private void setupViews() {
- final LayoutInflater mLayoutInflater = LayoutInflater.from(getContext());
- RelativeLayout rlTopNavbar = (RelativeLayout) mLayoutInflater.inflate(R.layout.top_menu_navbar, null);
- addView(rlTopNavbar);
- llShowMenu = (LinearLayout) rlTopNavbar.findViewById(R.id.ll_back);
- mLlDownList = (LinearLayout) rlTopNavbar.findViewById(R.id.ll_down_list);
- mLlRefresh = (LinearLayout) rlTopNavbar.findViewById(R.id.ll_refresh);
- tvTitle = (TextView) rlTopNavbar.findViewById(R.id.tv_title);
- tvRightOperationName = (TextView) rlTopNavbar.findViewById(R.id.tv_right_operation_name);
- ivDownListIcon = (ImageView) rlTopNavbar.findViewById(R.id.iv_down_list_icon);
- ivRefresh = (ImageView) rlTopNavbar.findViewById(R.id.iv_refresh);
- ivRightLine = (ImageView) rlTopNavbar.findViewById(R.id.iv_right_line);
- llShowMenu.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (mOnClickListener != null) {
- mOnClickListener.onClick();
- }
- }
- });
- }
- }
消息中心視圖的布局文件(message.xml):
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:background="#FFFFFF"
- android:orientation="vertical" >
- <com.everyone.android.widget.TopMenuNavbar
- android:id="@+id/rl_top_menu_navbar"
- style="@style/top_navbar" />
- </LinearLayout>
消息中心視圖的Java文件:
- package com.everyone.android.widget;
- import android.content.Context;
- import android.util.AttributeSet;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.FrameLayout;
- import android.widget.LinearLayout;
- import com.everyone.android.R;
- /**
- * 功能描述:消息中心視圖
- * @author android_ls
- */
- public class MessageLayout extends FrameLayout implements OnClickListener {
- private TopMenuNavbar topMenuNavbar;
- public TopMenuNavbar getTopMenuNavbar() {
- return topMenuNavbar;
- }
- public MessageLayout(Context context) {
- super(context);
- setupViews();
- }
- public MessageLayout(Context context, AttributeSet attrs) {
- super(context, attrs);
- setupViews();
- }
- private void setupViews() {
- final LayoutInflater mLayoutInflater = LayoutInflater.from(getContext());
- LinearLayout rlTopNavbar = (LinearLayout) mLayoutInflater.inflate(R.layout.message, null);
- addView(rlTopNavbar);
- topMenuNavbar = (TopMenuNavbar) rlTopNavbar.findViewById(R.id.rl_top_menu_navbar);
- topMenuNavbar.mLlRefresh.setOnClickListener(this);
- topMenuNavbar.tvTitle.setText("消息中心");
- topMenuNavbar.ivDownListIcon.setVisibility(View.GONE);
- topMenuNavbar.ivRefresh.setVisibility(View.GONE);
- }
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.ll_refresh:
- break;
- default:
- break;
- }
- }
- }
二、修改新鮮事視圖
修改後的新鮮事視圖布局文件(fresh_news.xml):
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:background="#FFFFFF"
- android:orientation="vertical" >
- <com.everyone.android.widget.TopMenuNavbar
- android:id="@+id/rl_top_menu_navbar"
- style="@style/top_navbar" />
- </LinearLayout>
修改後的新鮮事視圖的Java文件:
- package com.everyone.android.widget;
- import android.content.Context;
- import android.util.AttributeSet;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.FrameLayout;
- import android.widget.LinearLayout;
- import com.everyone.android.R;
- /**
- * 功能描述:新鮮事視圖
- * @author android_ls
- */
- public class FreshNewsLayout extends FrameLayout implements OnClickListener {
- private TopMenuNavbar topMenuNavbar;
- public TopMenuNavbar getTopMenuNavbar() {
- return topMenuNavbar;
- }
- public FreshNewsLayout(Context context) {
- super(context);
- setupViews();
- }
- public FreshNewsLayout(Context context, AttributeSet attrs) {
- super(context, attrs);
- setupViews();
- }
- private void setupViews() {
- final LayoutInflater mLayoutInflater = LayoutInflater.from(getContext());
- LinearLayout rlTopNavbar = (LinearLayout) mLayoutInflater.inflate(R.layout.fresh_news, null);
- addView(rlTopNavbar);
- topMenuNavbar = (TopMenuNavbar) rlTopNavbar.findViewById(R.id.rl_top_menu_navbar);
- topMenuNavbar.mLlDownList.setOnClickListener(this);
- topMenuNavbar.mLlRefresh.setOnClickListener(this);
- topMenuNavbar.ivRightLine.setVisibility(View.GONE);
- topMenuNavbar.tvRightOperationName.setVisibility(View.GONE);
- }
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.ll_down_list:
- break;
- case R.id.ll_refresh:
- break;
- default:
- break;
- }
- }
- }
三、左側菜單欄添加選中的Item事件監聽器
點擊左側菜單中某個組的Item後,要實現切換父容器中的視圖,那麼左側菜單對象就得持有父容器(我們自定義的滿足滑動顯示或隱藏左側菜單的ViewGroup)和各個視圖的引用。這樣,等於左側菜單與父容器和各個要切換的視圖都關聯起來了,也就是左側菜單與其它對象的耦合度高了,編寫代碼也變得復雜。如果硬要這麼做,有錯嗎?沒有。不過我不想這麼寫,在左側菜單類添加接口,將每次用戶單擊的Item的位置信息傳到外部。我們讓主界面Activity類去實現該接口,完成左側菜單拋出去的要響應的事件。(這塊不是很好描述,或者是我表達能力的問題吧。)
在父容器(ScrollerContainer)中添加切換視圖的方法:
- /**
- * 切換視圖
- * @param view
- */
- public void show(View view) {
- mPanelInvisible = false;
- int scrollX = getChildAt(1).getScrollX();
- mScroller.startScroll(scrollX, 0, -scrollX, 0, ANIMATION_DURATION_TIME);
- invalidate();
- removeViewAt(1);
- addView(view, 1, getLayoutParams());
- }
對外的接口:
- /**
- * 設置選中的Item事件監聽器
- * @param seletedListener
- */
- public void setOnSeletedListener(onSeletedListener seletedListener) {
- mOnSeletedListener = seletedListener;
- }
- /**
- * 選中的Item事件監聽器
- * @author android_ls
- */
- public interface onSeletedListener {
- /**
- * 當前選中的Item事件處理器
- * @param groupPosition 所屬組Id
- * @param childPosition 在所屬組內的位置
- */
- public abstract void seletedChildView(int groupPosition, int childPosition);
- }
組的Item單擊事件監聽器:
- mExpandableListView.setOnChildClickListener(new OnChildClickListener() {
- @Override
- public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
- if (mOnSeletedListener == null) {
- return false;
- }
- mGroupPosition = groupPosition;
- mChildPosition = childPosition;
- mOnSeletedListener.seletedChildView(groupPosition, childPosition);
- return true;
- }
- );
左側菜單修改後的完整源碼:
- package com.everyone.android.widget;
- import java.util.ArrayList;
- import java.util.List;
- import android.content.Context;
- import android.content.res.Resources;
- import android.util.AttributeSet;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.widget.ExpandableListView;
- import android.widget.ExpandableListView.OnChildClickListener;
- import android.widget.ExpandableListView.OnGroupClickListener;
- import android.widget.FrameLayout;
- import android.widget.ImageView;
- import android.widget.LinearLayout;
- import android.widget.TextView;
- import com.everyone.android.R;
- import com.everyone.android.adapter.LeftPanelExListViewAdapter;
- import com.everyone.android.entity.LeftPanelListItem;
- /**
- * 功能描述:仿人人主界面之左側面板
- * @author android_ls
- *
- */
- public class LeftPanelLayout extends FrameLayout {
- /**
- * 用戶圖標顯示組件
- */
- public ImageView ivUserIcon;
- /**
- * 用戶名稱顯示組件
- */
- public TextView tvNickname;
- /**
- * 可展開的ListView組件
- */
- private ExpandableListView mExpandableListView;
- /**
- * ExpandableListView組件的數據適配器
- */
- private LeftPanelExListViewAdapter mExListViewAdapter;
- /**
- * ExpandableListView組件的數據源
- */
- private List<LeftPanelListItem> mListItems = new ArrayList<LeftPanelListItem>();
- /**
- * 分組名數組
- */
- private String[] mGroupNames;
- private onSeletedListener mOnSeletedListener;
- private int mGroupPosition;
- private int mChildPosition;
- public LeftPanelLayout(Context context) {
- super(context);
- setupViews();
- }
- public LeftPanelLayout(Context context, AttributeSet attrs) {
- super(context, attrs);
- setupViews();
- }
- private void setupViews() {
- final LayoutInflater mInflater = LayoutInflater.from(getContext());
- LinearLayout viewRoot = (LinearLayout) mInflater.inflate(R.layout.left_panel, null);
- addView(viewRoot);
- ivUserIcon = (ImageView) viewRoot.findViewById(R.id.iv_user_icon);
- tvNickname = (TextView) viewRoot.findViewById(R.id.tv_nickname);
- mExpandableListView = (ExpandableListView) viewRoot.findViewById(R.id.elv_list_view);
- initialized();
- }
- private void initialized() {
- Resources resources = this.getResources();
- mGroupNames = resources.getStringArray(R.array.left_panel_group_names);
- String[] firstGroupNames = resources.getStringArray(R.array.left_panel_first_group_names);
- String[] secondGroupNames = resources.getStringArray(R.array.left_panel_second_group_names);
- String[] threeGroupNames = resources.getStringArray(R.array.left_panel_group_three_names);
- int[] firstGroupIcons = {
- R.drawable.left_panel_item_newsfeed_icon_selector,
- R.drawable.left_panel_item_message_icon_selector,
- R.drawable.left_panel_item_chat_icon_selector,
- R.drawable.left_panel_item_friends_icon_selector,
- R.drawable.left_panel_item_search_icon_selector };
- int[] secondGroupIcons = {
- R.drawable.left_panel_item_location_icon_selector,
- R.drawable.left_panel_item_mainpage_icon_selector,
- R.drawable.left_panel_item_hot_icon_selector,
- R.drawable.left_panel_item_apps_icon_selector };
- int[] threeGroupIcons = {
- R.drawable.left_panel_item_settings_icon_selector,
- R.drawable.left_panel_item_layout_icon_selector };
- addGroup(0, firstGroupNames, firstGroupIcons);
- addGroup(1, secondGroupNames, secondGroupIcons);
- addGroup(2, threeGroupNames, threeGroupIcons);
- mExListViewAdapter = new LeftPanelExListViewAdapter(getContext(), mListItems);
- mExpandableListView.setAdapter(mExListViewAdapter);
- // 設置默認讓所有組都展開
- for (int i = 0; i < mListItems.size(); i++) {
- mExpandableListView.expandGroup(i);
- }
- // 設置OnGroupClick時,不再展開或收縮組內的子項
- mExpandableListView.setOnGroupClickListener(new OnGroupClickListener() {
- @Override
- public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
- // 表示GroupItem的單擊事件已被處理
- return true;
- }
- });
- mExpandableListView.setOnChildClickListener(new OnChildClickListener() {
- @Override
- public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
- if (mOnSeletedListener == null) {
- return false;
- }
- mGroupPosition = groupPosition;
- mChildPosition = childPosition;
- mOnSeletedListener.seletedChildView(groupPosition, childPosition);
- return true;
- }
- });
- }
- /**
- * 添加數據到指定的組
- * @param groupId 組ID
- * @param names 子項的名字數組
- * @param icons 子項的圖標數組
- */
- private void addGroup(int groupId, String[] names, int[] icons) {
- LeftPanelListItem listItem = new LeftPanelListItem();
- listItem.setId(groupId);
- listItem.setName(mGroupNames[groupId]);
- // 組沒有操作指示圖標
- // listItem.setDrawableId(drawableId);
- ArrayList<LeftPanelListItem> firstGroup = new ArrayList<LeftPanelListItem>();
- for (int i = 0; i < names.length; i++) {
- LeftPanelListItem firstGroupItem = new LeftPanelListItem();
- firstGroupItem.setId(i);
- firstGroupItem.setName(names[i]);
- firstGroupItem.setDrawableId(icons[i]);
- // 可以無限延伸
- // firstGroupItem.setGroups(null);
- firstGroup.add(firstGroupItem);
- }
- listItem.setGroups(firstGroup);
- mListItems.add(listItem);
- }
- /**
- * 設置選中的Item事件監聽器
- * @param seletedListener
- */
- public void setOnSeletedListener(onSeletedListener seletedListener) {
- mOnSeletedListener = seletedListener;
- }
- /**
- * 選中的Item事件監聽器
- * @author android_ls
- */
- public interface onSeletedListener {
- /**
- * 當前選中的Item事件處理器
- * @param groupPosition 所屬組Id
- * @param childPosition 在所屬組內的位置
- */
- public abstract void seletedChildView(int groupPosition, int childPosition);
- }
- }
- package com.everyone.android.ui;
- import android.os.Bundle;
- import android.view.ViewGroup.LayoutParams;
- import com.everyone.android.AppBaseActivity;
- import com.everyone.android.api.OnMenuClickListener;
- import com.everyone.android.widget.FreshNewsLayout;
- import com.everyone.android.widget.LeftPanelLayout;
- import com.everyone.android.widget.LeftPanelLayout.onSeletedListener;
- import com.everyone.android.widget.MessageLayout;
- import com.everyone.android.widget.ScrollerContainer;
- /**
- * 功能描述:應用主界面
- * @author android_ls
- */
- public class EveryoneActivity extends AppBaseActivity implements OnMenuClickListener, onSeletedListener {
- /**
- * 滾動(滑動)容器
- */
- private ScrollerContainer mSlideContainer;
- /**
- * 左側面板
- */
- private LeftPanelLayout mLeftPanelLayout;
- /**
- * 新鮮事
- */
- private FreshNewsLayout mFreshNewsLayout;
- /**
- * 消息
- */
- private MessageLayout mMessageLayout;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(mSlideContainer);
- }
- @Override
- protected int getLayoutId() {
- return 0;
- }
- @Override
- protected void setupView() {
- mSlideContainer = new ScrollerContainer(mContext);
- mLeftPanelLayout = new LeftPanelLayout(mContext);
- mLeftPanelLayout.setOnSeletedListener(this);
- mFreshNewsLayout = new FreshNewsLayout(mContext);
- mMessageLayout = new MessageLayout(mContext);
- mFreshNewsLayout.getTopMenuNavbar().setOnClickListener(this);
- mMessageLayout.getTopMenuNavbar().setOnClickListener(this);
- LayoutParams layoutParams = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
- mSlideContainer.addView(mLeftPanelLayout, 0, layoutParams);
- mSlideContainer.addView(mFreshNewsLayout, 1, layoutParams);
- }
- @Override
- protected void initialized() {
- // TODO Auto-generated method stub
- }
- @Override
- public void onClick() {
- mSlideContainer.show();
- }
- @Override
- public void seletedChildView(int groupPosition, int childPosition) {
- switch (groupPosition) {
- case 0: // 第一組
- switch (childPosition) {
- case 0:
- mSlideContainer.show(mFreshNewsLayout);
- break;
- case 1:
- mSlideContainer.show(mMessageLayout);
- break;
- case 2:
- break;
- case 3:
- break;
- case 4:
- break;
- default:
- break;
- }
- break;
- case 1: // 第二組
- switch (childPosition) {
- case 0:
- break;
- case 1:
- break;
- case 2:
- break;
- case 3:
- break;
- default:
- break;
- }
- break;
- case 2: // 第三組
- switch (childPosition) {
- case 0:
- break;
- case 1:
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- }
- }
五、效果圖:
新鮮事視圖
點擊頂部左側Menu按鈕後
點擊左側菜單的消息Item
松開手後的中心消息視圖
轉自:http://blog.csdn.net/android_ls/article/details/8765193
本文開始將為大家剖析Android示例程序-Snake貪吃蛇。貪吃蛇游戲大部分
本文為大家分享Android自定義Spinner適配器的相關知識點,供大家參考,具體內容如下 一、大致效果 二.關鍵代碼 在注釋中講重點吧。 (1)Spinn
可以顯示在的Android任務,通過加載進度條的進展。進度條有兩種形狀。加載欄和加載微調(spinner)。在本章中,我們將討論微調(spinner)。Spinner 用
本文實例講述了Android編程使WebView支持HTML5 Video全屏播放的解決方法。分享給大家供大家參考,具體如下: 1)需要在AndroidManif