安卓音乐播放器--侧边栏

本文介绍了如何在安卓应用中实现侧边栏音乐播放器,通过学习参考资料并解决在ScrollView中添加水平视图的问题。在解决过程中,避免使用透明层,而是直接将menuLayout作为children,但遇到已存在父节点的错误。通过将menuLayout的MyHorizontalScrollView单独写入XML并在setContentView时设置,调整onGlobalLayout中添加children的顺序,最终实现了从右侧滑出的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

侧边栏学习

参考资料:http://www.chinatarena.com/Html/adpeixun/201307/5251.html

还有一个参考的代码 最后自己的理解是 在scrollView中添加两个水平的视图 

		musicListLayout.findViewById(R.id.btnMusicListSlide).setOnClickListener(new MusicListActivity.ClickListenerForScrolling(scrollView, menu));
		final View[] children=new View[]{menuLayout,musicListLayout};
		int scrollToViewIdx=0;
		scrollView.initViews(children, scrollToViewIdx, new MusicListActivity.SizeCallbackForMenu(musicListLayout.findViewById(R.id.btnMusicListSlide))
之前使用一个透明的TextView替代menuLayout 之前的menuLayout如下:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent"
    android:layout_height="fill_parent" android:background="#00ffffff" android:padding="0px" android:layout_margin="0px">

    <!--
    This ImageView is used as a menu.
    --><!-- 
    <ImageView android:id="@+id/menu" android:src="@drawable/fb_menu" android:layout_width="fill_parent"
        android:layout_height="fill_parent" android:scaleType="fitStart" />
         -->
    <LinearLayout 
        android:id="@+id/menu"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical"
        android:layout_gravity="right"
        >
        <Button 
            android:id="@+id/playMode"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="测试"
            />
        <Button 
            android:id="@+id/btnExit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="退出"
            />
    </LinearLayout>


    This HorizontalScrollView will contain a LinearLayout that will contain a transparent
    View (that allows the menu above to show through) and the other application Views.
  
    <com.vanhon.mediaplayer2.view.MyHorizontalScrollView android:id="@+id/myScrollView"
        android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#00ffffff" android:padding="0px"
        android:layout_margin="0px" android:fadingEdge="none" android:fadingEdgeLength="0px" android:scrollbars="none">

        <LinearLayout android:id="@+id/top" android:layout_height="fill_parent" android:layout_width="fill_parent"
            android:orientation="horizontal" android:background="#00ffffff" android:padding="0px" android:layout_margin="0px">
 
        </LinearLayout>

    </com.vanhon.mediaplayer2.view.MyHorizontalScrollView>


</FrameLayout>

采用帧布局 在菜单滑出时透明层将app“挤”过去一些 由于是帧布局 其上是透明层 于是就把底下的menu显示出来(网上下载的demo)后想改成右边的菜单栏 无法实现 每次都会显示成菜单的后半段 如图

之前没太明白为什么 后来想 这样透明层是推开了 但是底下的还是没变 所以会这样吧 于是后来不用透明层 直接用menuLayout 作为children 但是会报错 


意思是它已经有了一个父节点 然后将menuLayout中的MyHorizontalScrollView单独写成一个xml 然后在setContentView时设置为MyHorizontalScrollView 在MyHorizontalScrollView代码中更改了onGlobalLayout中添加children的顺序 于是就能从右边滑出 至于为什么 我可以说是一种直觉么。。 哈哈 下面贴上MyHorizontalScrollView 的代码(其实百度一下有超多的)

/*
 * #%L
 * SlidingMenuDemo
 * $Id:$
 * $HeadURL:$
 * %%
 * Copyright (C) 2012 Paul Grime
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
package com.vanhon.mediaplayer2.view;

import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.HorizontalScrollView;

/**
 * A HorizontalScrollView (HSV) implementation that disallows touch events (so no scrolling can be done by the user).
 * 
 * This HSV MUST contain a single ViewGroup as its only child, and this ViewGroup will be used to display the children Views
 * passed in to the initViews() method.
 */
public class MyHorizontalScrollView extends HorizontalScrollView {
    public MyHorizontalScrollView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }

    public MyHorizontalScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public MyHorizontalScrollView(Context context) {
        super(context);
        init(context);
    }

    void init(Context context) {
        // remove the fading as the HSV looks better without it
        setHorizontalFadingEdgeEnabled(false);
        setVerticalFadingEdgeEnabled(false);
    }

    /**
     * @param children
     *            The child Views to add to parent.
     * @param scrollToViewIdx
     *            The index of the View to scroll to after initialisation.
     * @param sizeCallback
     *            A SizeCallback to interact with the HSV.
     */
    public void initViews(View[] children, int scrollToViewIdx, SizeCallback sizeCallback) {
        // A ViewGroup MUST be the only child of the HSV
        ViewGroup parent = (ViewGroup) getChildAt(0);

        // Add all the children, but add them invisible so that the layouts are calculated, but you can't see the Views
        for (int i = 0; i <children.length ; i++) {
            children[i].setVisibility(View.INVISIBLE);
            parent.addView(children[i]);
        }

        // Add a layout listener to this HSV
        // This listener is responsible for arranging the child views.
        OnGlobalLayoutListener listener = new MyOnGlobalLayoutListener(parent, children, scrollToViewIdx, sizeCallback);
        getViewTreeObserver().addOnGlobalLayoutListener(listener);
//        System.out.println("initViews完毕");
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        // Do not allow touch events.
        return false;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        // Do not allow touch events.
        return false;
    }

    /**
     * An OnGlobalLayoutListener impl that passes on the call to onGlobalLayout to a SizeCallback, before removing all the Views
     * in the HSV and adding them again with calculated widths and heights.
     */
    class MyOnGlobalLayoutListener implements OnGlobalLayoutListener {
        ViewGroup parent;
        View[] children;
        int scrollToViewIdx;
        int scrollToViewPos = 0;
        SizeCallback sizeCallback;

        /**
         * @param parent
         *            The parent to which the child Views should be added.
         * @param children
         *            The child Views to add to parent.
         * @param scrollToViewIdx
         *            The index of the View to scroll to after initialisation.
         * @param sizeCallback
         *            A SizeCallback to interact with the HSV.
         */
        public MyOnGlobalLayoutListener(ViewGroup parent, View[] children, int scrollToViewIdx, SizeCallback sizeCallback) {
            this.parent = parent;
            this.children = children;
            this.scrollToViewIdx = scrollToViewIdx;
            this.sizeCallback = sizeCallback;
        }

        @Override
        public void onGlobalLayout() {
             System.out.println("onGlobalLayout");

            final HorizontalScrollView me = MyHorizontalScrollView.this;

            // The listener will remove itself as a layout listener to the HSV
            me.getViewTreeObserver().removeGlobalOnLayoutListener(this);

            // Allow the SizeCallback to 'see' the Views before we remove them and re-add them.
            // This lets the SizeCallback prepare View sizes, ahead of calls to SizeCallback.getViewSize().
            sizeCallback.onGlobalLayout();

            parent.removeViewsInLayout(0, children.length);

            final int w = me.getMeasuredWidth();
            final int h = me.getMeasuredHeight();

            // System.out.println("w=" + w + ", h=" + h);

            // Add each view in turn, and apply the width and height returned by the SizeCallback.
            int[] dims = new int[2];
            scrollToViewPos = 0;
//            for (int i = 0; i <children.length; i++) {
            for (int i = children.length-1; i >=0; i--) {
                sizeCallback.getViewSize(i, w, h, dims);
//                 System.out.println("addView w=" + dims[0] + ", h=" + dims[1]+",i="+i);
                children[i].setVisibility(View.VISIBLE);
                parent.addView(children[i], dims[0], dims[1]);
                if (i < scrollToViewIdx) {
                    scrollToViewPos += dims[0];
                }
            }

            // For some reason we need to post this action, rather than call immediately.
            // If we try immediately, it will not scroll.
            new Handler().post(new Runnable() {
                @Override
                public void run() {
                    me.scrollBy(scrollToViewPos, 0);
                }
            });
        }
    }

    /**
     * Callback interface to interact with the HSV.
     */
    public interface SizeCallback {
        /**
         * Used to allow clients to measure Views before re-adding them.
         */
        public void onGlobalLayout();

        /**
         * Used by clients to specify the View dimensions.
         * 
         * @param idx
         *            Index of the View.
         * @param w
         *            Width of the parent View.
         * @param h
         *            Height of the parent View.
         * @param dims
         *            dims[0] should be set to View width. dims[1] should be set to View height.
         */
        public void getViewSize(int idx, int w, int h, int[] dims);
    }
}
最后的效果图:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值