当前位置: 代码迷 >> Android >> Android仿人们客户端(v5.7.1)——点击左侧菜单栏中的Item切换视图
  详细解决方案

Android仿人们客户端(v5.7.1)——点击左侧菜单栏中的Item切换视图

热度:105   发布时间:2016-05-01 10:55:41.0
Android仿人人客户端(v5.7.1)——点击左侧菜单栏中的Item切换视图

转载请标明出处:http://blog.csdn.net/android_ls/article/details/8765193

       在前面几讲中,左侧菜单(左侧面板)、满足滑动或点击子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

       松开手后的中心消息视图

 

1楼zwhe昨天 15:14
如可以,是否code发送至 262323618
Re: android_ls昨天 15:24
回复zwhen源码,我后面会发到CSDN的资源上。目前还未完成,不方便分享源码。
  相关解决方案