Android实现网易新闻客户端侧滑菜单(2)

前面已经讲过通过三方开源库SlideMenu来实现这种效果,请参考Android实现网易新闻客户端侧滑菜单(一)

今天通过自定义View来实现这种功能。

代码如下:

SlideMenu.java

package com.jackie.slidemenu.view; 

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.Scroller; 

public class SlideMenu extends ViewGroup { 

 private int mMostRecentX;  // 最后一次x轴的偏移量 

 private final int MENU_SCREEN = 0;  // 菜单界面
 private final int MAIN_SCREEN = 1;  // 主界面
 private int mCurrentScreen = MAIN_SCREEN;  // 当前屏幕显示的是主界面
 private Scroller mScroller; 

 private int touchSlop; 

 public SlideMenu(Context context, AttributeSet attrs) {
  super(context, attrs);
  mScroller = new Scroller(context); 

  touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
 } 

 /**
  * 测量出所有子布局的宽和高
  */
 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  super.onMeasure(widthMeasureSpec, heightMeasureSpec); 

  measureView(widthMeasureSpec, heightMeasureSpec);
 } 

 /**
  * 测量所有子布局的宽和高
  * @param widthMeasureSpec 父布局也就是ViewGroup的宽度测量规格
  * @param heightMeasureSpec 父布局也就是ViewGroup的高度测量规格
  */
 private void measureView(int widthMeasureSpec, int heightMeasureSpec) {
  // 测量菜单的宽和高
  View menuView = getChildAt(0);
  menuView.measure(menuView.getLayoutParams().width, heightMeasureSpec); 

  // 测量主界面的宽和高
  View mainView = getChildAt(1);
  mainView.measure(widthMeasureSpec, heightMeasureSpec);  // 主界面的宽和高和父控件viewgroup的宽高一样
 } 

 @Override
 protected void onLayout(boolean changed, int l, int t, int r, int b) {
  // 布置菜单的位置
  View menuView = getChildAt(0);
  menuView.layout(-menuView.getMeasuredWidth(), 0, 0, b); 

  // 布置主界面的位置
  View mainView = getChildAt(1);
  mainView.layout(0, 0, r, b);
 } 

 @Override
 public boolean onTouchEvent(MotionEvent event) {
  switch (event.getAction()) {
  case MotionEvent.ACTION_DOWN:
   mMostRecentX = (int) event.getX();
   break;
  case MotionEvent.ACTION_MOVE:
   // 最新的x轴偏移量
   int moveX = (int) event.getX(); 

   // 增量值
   int deltaX = mMostRecentX - moveX; 

   // 把最新的x轴偏移量赋值给成员变量
   mMostRecentX = moveX; 

   // 得到x轴移动后的偏移量
   int newScrollX = getScrollX() + deltaX; 

   if(newScrollX < -getChildAt(0).getWidth()) {  // 当前屏幕x轴的偏移量超过了菜单的左边界
    // 回到菜单的左边界位置
    scrollTo(-getChildAt(0).getWidth(), 0);
   } else if(newScrollX > 0) {  // 超过了主界面的右边界
    // 回到主界面的右边界
    scrollTo(0, 0);
   } else {
    scrollBy(deltaX, 0);
   }
   break;
  case MotionEvent.ACTION_UP:
   int scrollX = getScrollX();  // x轴最新的偏移量 

   int menuXCenter = -getChildAt(0).getWidth() / 2;  // 菜单x轴的中心点 

   if(scrollX > menuXCenter) { // 切换到主界面
    mCurrentScreen = MAIN_SCREEN;
   } else { // 切换到菜单界面
    mCurrentScreen = MENU_SCREEN;
   }
   switchScreen();
   break;
  default:
   break;
  }
  return true;
 } 

 /**
  * 根据mCurrentScreen切换屏幕
  */
 private void switchScreen() {
  int scrollX = getScrollX(); // 当前x轴的偏移量
  int dx = 0; 

  if(mCurrentScreen == MAIN_SCREEN) { // 切换到主界面
//   scrollTo(0, 0);
   dx = 0 - scrollX;
  } else if(mCurrentScreen == MENU_SCREEN) { // 切换到菜单界面
//   scrollTo(-getChildAt(0).getWidth(), 0);
   dx = -getChildAt(0).getWidth() - scrollX;
  } 

  mScroller.startScroll(scrollX, 0, dx, 0, Math.abs(dx) * 5); 

  invalidate();  // invalidate -> drawChild -> child.draw -> computeScroll
 } 

 /**
  * invalidate出发此方法, 更新屏幕的x轴的偏移量
  */
 @Override
 public void computeScroll() {
  if(mScroller.computeScrollOffset()) {  // 判断是否正在模拟数据中, true 正在进行 false 数据模拟完毕
   scrollTo(mScroller.getCurrX(), 0); 

   invalidate();  // 引起computeScroll的调用
  }
 } 

 /**
  * 是否显示菜单
  * @return
  */
 public boolean isShowMenu() {
  return mCurrentScreen == MENU_SCREEN;
 } 

 /**
  * 隐藏菜单
  */
 public void hideMenu() {
  mCurrentScreen = MAIN_SCREEN;
  switchScreen();
 } 

 /**
  * 显示菜单
  */
 public void showMenu() {
  mCurrentScreen = MENU_SCREEN;
  switchScreen();
 } 

 /**
  * 拦截事件的方法
  */
 @Override
 public boolean onInterceptTouchEvent(MotionEvent ev) {
  switch (ev.getAction()) {
  case MotionEvent.ACTION_DOWN:
   mMostRecentX = (int) ev.getX();
   break;
  case MotionEvent.ACTION_MOVE: 

   int diffX = (int) (ev.getX() - mMostRecentX);
   if(Math.abs(diffX) > touchSlop) {
    return true;
   }
   break;
  default:
   break;
  }
  return super.onInterceptTouchEvent(ev);
 } 

} 

MainActivity.java

package com.jackie.slidemenu; 

import com.jackie.slidemenu.view.SlideMenu; 

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.TextView;
import android.widget.Toast; 

public class MainActivity extends Activity implements OnClickListener { 

 private SlideMenu mSlideMenu; 

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  // 去除标题, 需要在setContentView之前调用
  requestWindowFeature(Window.FEATURE_NO_TITLE);
  setContentView(R.layout.activity_main); 

  mSlideMenu = (SlideMenu) findViewById(R.id.slidemenu);
  findViewById(R.id.iv_slidemenu_main_back).setOnClickListener(this); 

 } 

 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
  // Inflate the menu; this adds items to the action bar if it is present.
  getMenuInflater().inflate(R.menu.main, menu);
  return true;
 } 

 @Override
 public void onClick(View v) {
  if(mSlideMenu.isShowMenu()) {
   mSlideMenu.hideMenu();
  } else {
   mSlideMenu.showMenu();
  }
 } 

 public void click(View v) {
  TextView tv = (TextView) v;
  Toast.makeText(this, tv.getText(), 0).show();
 }
}

系列文章:

Android实现网易新闻客户端效果

Android实现网易新闻客户端侧滑菜单(1)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android模拟实现网易新闻客户端

    首先我们先看一下要模拟的界面 我们主要实现的就是ListView解析json文件中的数据,UI布局很简单不做赘述. 这里我们需要一个服务器来实现数据的动态更新, 这里我们用到的是Tomcat8.0. 首先我们把需要解析的json文件放置到Tomcat的webapp文件下的ROOT里面,方便我们解析. 首先我们创建一个JsonParse类用来解析json文件: package cn.edu.bzu.myapplication.Tools; import com.google.gson.Gson;

  • Android实现网易新闻客户端首页效果

    关于实现网易新闻客户端的界面,以前写过很多博客,请参考: Android实现网易新闻客户端效果 Android实现网易新闻客户端侧滑菜单(一) Android实现网易新闻客户端侧滑菜单(二) 今天用ViewPager + FragmentAdapter + ViewPagerIndicator来实现. ViewPagerIndicator是一款分页指标小部件兼容ViewPager,封装上做得非常不错,目前已为众多知名应用所使用.具体API的使用,大家可以下载官方demo示例研究研究就知道啦! 下

  • 基于PHP后台的Android新闻浏览客户端

    本文实例为大家分享了Android新闻浏览客户端,基于php后台,供大家参考,具体内容如下 1.使用HBuilder进行PHP环境配置,测试是否可以查询MySQL语句,之前都已经详细说明过了. 2.此处php后台实现mysql的查询功能,并以JSON数据格式返回个客户端 在PHP此处建立一个mysql_connect.php文件,实现数据库的连接,并设置字符集格式. <?php $con = mysql_connect("localhost","root",&

  • Android网络编程之简易新闻客户端

    一. 通过一个案例"新闻客户端"向大家演示AsyncHttpClient和SmartImageView的综合使用. 运行结果如下: 1.首先我们了解一下相关知识: SmartImageView的使用 市面上一些常见软件,例如手机QQ.天猫.京东商场等,都加载了大量网络上的图片.用Android自带的API实现这一功能十分麻烦而且耗时.为此,编程爱好者开发了一个开源项目--SmartImageView. https://github.com/loopj/android-smart-ima

  • Android打造属于自己的新闻平台(客户端+服务器)

    完全属于自己的新闻展示平台,展示给大家,希望大家喜欢. 一.新闻的数据库的构建 脚本代码如下:(使用的mysql5.0 数据库) SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; SET time_zone = "+00:00"; -- Database: `newsdemo` -- 表的结构 `news` CREATE TABLE IF NOT EXISTS `news` ( `id` int(10) NOT NULL AUTO_IN

  • Android 仿网易新闻客户端分类排序功能

    先来看看网易新闻客户端以及自己实现的效果图,效果当然还是网易的好 gridviewsort.gif 如何实现拖拽一个Item 用WindowManager添加一个ImageView,并且将这个ImageView的显示图片设置成被拖拽item的截图,截图可以通过View的getDrawingCache获得.拖拽的时候,隐藏原始的item.处理触摸事件的ActionMove,调整ImageView的位置,跟随手指移动.在ActionUp的时候removeView GridView @Override

  • Android实现网易新闻客户端侧滑菜单(1)

    Android中很多产品(比如360手机助手.网易菜单...)都采用侧滑菜单的展现形式,采用这种展现形式 1.能把更多的展现内容都存放在菜单中 2.设计上也能体现出视觉效果 现在这种交互方式越来越流行了,虽然这种交互方式可以通过自定义组件的方式来实现,但是用三方开源库更简单. SlidingMenu:SlidingMenu的是一种比较新的设置界面或配置界面效果,在主界面左滑或者右滑出现设置界面,能方便的进行各种操作.目前有大量的应用都在使用这一效果. 地址:https://github.com/

  • Android实现网易新闻客户端侧滑菜单(2)

    前面已经讲过通过三方开源库SlideMenu来实现这种效果,请参考Android实现网易新闻客户端侧滑菜单(一) 今天通过自定义View来实现这种功能. 代码如下: SlideMenu.java package com.jackie.slidemenu.view; import android.content.Context; import android.graphics.Canvas; import android.util.AttributeSet; import android.view

  • Android自定义View 仿QQ侧滑菜单的实现代码

    先看看QQ的侧滑效果 分析一下 先上原理图(不知道能否表达的清楚 ==) -首先这里使用了 Android 的HorizontalScrollView 水平滑动布局作为容器,当然我们需要继承它自定义一个侧滑视图 - 这个容器里面有一个父布局(一般用LinerLayout,本demo用的是),这个父布局里面有且只有两个子控件(布局),初始状态菜单页的位置在Y轴上存在偏移这样可以就可以形成主页叠在菜单页的上方的视觉效果:然后在滑动的过程程中 逐渐修正偏移,最后菜单页和主页并排排列.原理搞清了实现起来

  • Android学习教程之分类侧滑菜单(5)

    本文实例为大家分享了Android分类侧滑菜单的制作方法,供大家参考,具体内容如下 classificmenuActivity.java代码: package com.siso.crazyworld; import android.animation.Animator; import android.content.res.Configuration; import android.graphics.Color; import android.graphics.drawable.BitmapDr

  • Android自定义HorizontalScrollView实现qq侧滑菜单

    今天看了鸿洋_大神在慕课网讲的qq5.0侧滑菜单.学了不少的知识,同时也佩服鸿洋_大神思路的清晰. 看了教程课下也自己实现了一下.代码几乎完全相同  别喷我啊..没办法 o(︶︿︶)o 唉 像素不好 没办法 找不到好的制作gif的软件. 我们暂且称侧滑左边界面的为menu,右边为content 首先是menu的布局 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:androi

  • Android使用DrawerLayout实现双向侧滑菜单

    前言   在android开发中,很多的app都有使用侧滑菜单,有的是自定义控件来实现侧滑菜单,但是android给我们提供了DrawerLayout类来实现侧滑菜单,侧滑效果很好,今天我就说说怎么去使用它来实现侧滑菜单. 实现   我们先来看一下效果图: 这里我们实现的双向侧滑菜单,在界面上部加入了两个按钮,点击就会打开菜单或者关闭菜单,当然也可以自己去滑动. 布局文件的代码: <LinearLayout xmlns:android="http://schemas.android.com

  • 仿网易新闻客户端头条ViewPager嵌套实例

    要点: 1.重写组件public boolean onInterceptTouchEvent(MotionEvent event)方法 2.正确使用requestDisallowInterceptTouchEvent(boolean flag)方法 关于以上两个方法,请大家多看看相关介绍,这里就不在叙述了^_^ 接下来上例子: 1.外层ViewPager布局 (假定文件名为viewpager_layout.xml) 复制代码 代码如下: <?xml version="1.0" e

随机推荐