zoukankan      html  css  js  c++  java
  • android 滑动菜单SlidingMenu的实现 (转)

    首先我们看下面视图:

    这种效果大家都不陌生,网上好多都说是仿人人网的,估计人家牛逼出来的早吧,我也参考了一一些例子,实现起来有三种方法,我下面简单介绍下:

    方法一:其实就是对GestureDetector手势的应用及布局文件的设计.

    布局文件main.xml 采用RelativeLayout布局.

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     3     android:layout_width="fill_parent"
     4     android:layout_height="fill_parent"
     5     android:orientation="vertical" >
     6 
     7  
     8 
     9     <LinearLayout
    10         android:id="@+id/layout_right"
    11         android:layout_width="fill_parent"
    12         android:layout_height="fill_parent"
    13         android:layout_marginLeft="50dp"
    14         android:orientation="vertical" >
    15 
    16  
    17 
    18         <AbsoluteLayout
    19             android:layout_width="fill_parent"
    20             android:layout_height="wrap_content"
    21             android:background="@color/grey21"
    22             android:padding="10dp" >
    23 
    24  
    25 
    26             <TextView
    27                 android:layout_width="wrap_content"
    28                 android:layout_height="wrap_content"
    29                 android:text="设置"
    30                 android:textColor="@android:color/background_light"
    31                 android:textSize="20sp" />
    32         </AbsoluteLayout>
    33 
    34  
    35 
    36         <ListView
    37             android:id="@+id/lv_set"
    38             android:layout_width="fill_parent"
    39             android:layout_height="fill_parent"
    40             android:layout_weight="1" >
    41         </ListView>
    42     </LinearLayout>
    43 
    44  
    45 
    46     <LinearLayout
    47         android:id="@+id/layout_left"
    48         android:layout_width="fill_parent"
    49         android:layout_height="fill_parent"
    50         android:background="@color/white"
    51         android:orientation="vertical" >
    52 
    53  
    54 
    55         <RelativeLayout
    56             android:layout_width="fill_parent"
    57             android:layout_height="wrap_content"
    58             android:background="@drawable/nav_bg" >
    59 
    60  
    61 
    62             <ImageView
    63                 android:id="@+id/iv_set"
    64                 android:layout_width="wrap_content"
    65                 android:layout_height="wrap_content"
    66                 android:layout_alignParentRight="true"
    67                 android:layout_alignParentTop="true"
    68                 android:src="@drawable/nav_setting" />
    69 
    70  
    71 
    72             <TextView
    73                 android:layout_width="wrap_content"
    74                 android:layout_height="wrap_content"
    75                 android:layout_centerInParent="true"
    76                 android:text="我"
    77                 android:textColor="@android:color/background_light"
    78                 android:textSize="20sp" />
    79         </RelativeLayout>
    80 
    81  
    82 
    83         <ImageView
    84             android:id="@+id/iv_set"
    85             android:layout_width="fill_parent"
    86             android:layout_height="fill_parent"
    87             android:scaleType="fitXY"
    88             android:src="@drawable/bg_guide_5" />
    89     </LinearLayout>
    90 
    91  
    92 
    93 </RelativeLayout>

    layout_right:这个大布局文件,layout_left:距离左边50dp像素.(我们要移动的是layout_left).

    看到这个图我想大家都很清晰了吧,其实:我们就是把layout_left这个布局控件整理向左移动,至于移动多少,就要看layout_right有多宽了。layout_left移动到距离左边的边距就是layout_right的宽及-MAX_WIDTH.相信大家都理解.

    布局文件就介绍到这里,下面看代码.

     1 /***
     2   * 初始化view
     3   */
     4  void InitView() {
     5   layout_left = (LinearLayout) findViewById(R.id.layout_left);
     6   layout_right = (LinearLayout) findViewById(R.id.layout_right);
     7   iv_set = (ImageView) findViewById(R.id.iv_set);
     8   lv_set = (ListView) findViewById(R.id.lv_set);
     9   lv_set.setAdapter(new ArrayAdapter<String>(this, R.layout.item,
    10     R.id.tv_item, title));
    11   lv_set.setOnItemClickListener(new OnItemClickListener() {
    12 
    13  
    14 
    15    @Override
    16    public void onItemClick(AdapterView<?> parent, View view,
    17      int position, long id) {
    18     Toast.makeText(MainActivity.this, title[position], 1).show();
    19    }
    20   });
    21   layout_left.setOnTouchListener(this);
    22   iv_set.setOnTouchListener(this);
    23   mGestureDetector = new GestureDetector(this);
    24   // 禁用长按监听
    25   mGestureDetector.setIsLongpressEnabled(false);
    26   getMAX_WIDTH();
    27  }
    28 
    29 这里要对手势进行监听,我想大家都知道怎么做,在这里我要说明一个方法:
    30 
    31 /***
    32   * 获取移动距离 移动的距离其实就是layout_left的宽度
    33   */
    34  void getMAX_WIDTH() {
    35   ViewTreeObserver viewTreeObserver = layout_left.getViewTreeObserver();
    36   // 获取控件宽度
    37   viewTreeObserver.addOnPreDrawListener(new OnPreDrawListener() {
    38    @Override
    39    public boolean onPreDraw() {
    40     if (!hasMeasured) {
    41      window_width = getWindowManager().getDefaultDisplay()
    42        .getWidth();
    43      RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) layout_left
    44        .getLayoutParams();
    45      layoutParams.width = window_width;
    46      layout_left.setLayoutParams(layoutParams);
    47      MAX_WIDTH = layout_right.getWidth();
    48      Log.v(TAG, "MAX_WIDTH=" + MAX_WIDTH + "width="
    49        + window_width);
    50      hasMeasured = true;
    51     }
    52     return true;
    53    }
    54   });
    55 
    56  }

    在这里我们要获取屏幕的宽度,并将屏幕宽度设置给layout_left这个控件,为什么要这么做呢因为如果不把该控件宽度写死的话,那么系统将认为layout_left会根据不同环境宽度自动适应,也就是说我们通过layout_left.getLayoutParams动态移动该控件的时候,该控件会伸缩而不是移动。描述的有点模糊,大家请看下面示意图就明白了.


     

    getLayoutParams可以很清楚看到,layout_left被向左拉伸了,并不是我们要的效果.

    还有一种解决办法就是我们在配置文件中直接把layout_left宽度写死,不过这样不利于开发,因为分辨率的问题.因此就用ViewTreeObserver进行对layout_left设置宽度.

    ViewTreeObserver,这个类主要用于对布局文件的监听.强烈建议同学们参考这篇文章 android ViewTreeObserver详细讲解,相信让你对ViewTreeObserver有更一步的了解.

    其他的就是对GestureDetector手势的应用,下面我把代码贴出来:

      1 package com.jj.slidingmenu;
      2 
      3  
      4 
      5 import android.app.Activity;
      6 import android.os.AsyncTask;
      7 import android.os.Bundle;
      8 import android.util.Log;
      9 import android.view.GestureDetector;
     10 import android.view.KeyEvent;
     11 import android.view.MotionEvent;
     12 import android.view.View;
     13 import android.view.ViewTreeObserver;
     14 import android.view.ViewTreeObserver.OnPreDrawListener;
     15 import android.view.Window;
     16 import android.view.View.OnTouchListener;
     17 import android.widget.AdapterView;
     18 import android.widget.AdapterView.OnItemClickListener;
     19 import android.widget.ArrayAdapter;
     20 import android.widget.ImageView;
     21 import android.widget.LinearLayout;
     22 import android.widget.ListView;
     23 import android.widget.RelativeLayout;
     24 import android.widget.Toast;
     25 import android.widget.LinearLayout.LayoutParams;
     26 
     27  
     28 
     29 /***
     30  * 滑动菜单
     31  * 
     32  * @author jjhappyforever...
     33  * 
     34  */
     35 public class MainActivity extends Activity implements OnTouchListener,
     36   GestureDetector.OnGestureListener {
     37  private boolean hasMeasured = false;// 是否Measured.
     38  private LinearLayout layout_left;
     39  private LinearLayout layout_right;
     40  private ImageView iv_set;
     41  private ListView lv_set;
     42 
     43  
     44 
     45  /** 每次自动展开/收缩的范围 */
     46  private int MAX_WIDTH = 0;
     47  /** 每次自动展开/收缩的速度 */
     48  private final static int SPEED = 30;
     49 
     50  
     51 
     52  private GestureDetector mGestureDetector;// 手势
     53  private boolean isScrolling = false;
     54  private float mScrollX; // 滑块滑动距离
     55  private int window_width;// 屏幕的宽度
     56 
     57  
     58 
     59  private String TAG = "jj";
     60 
     61  
     62 
     63  private String title[] = { "待发送队列", "同步分享设置", "编辑我的资料", "找朋友", "告诉朋友",
     64    "节省流量", "推送设置", "版本更新", "意见反馈", "积分兑换", "精品应用", "常见问题", "退出当前帐号" };
     65 
     66  
     67 
     68  /***
     69   * 初始化view
     70   */
     71  void InitView() {
     72   layout_left = (LinearLayout) findViewById(R.id.layout_left);
     73   layout_right = (LinearLayout) findViewById(R.id.layout_right);
     74   iv_set = (ImageView) findViewById(R.id.iv_set);
     75   lv_set = (ListView) findViewById(R.id.lv_set);
     76   lv_set.setAdapter(new ArrayAdapter<String>(this, R.layout.item,
     77     R.id.tv_item, title));
     78   lv_set.setOnItemClickListener(new OnItemClickListener() {
     79 
     80  
     81 
     82    @Override
     83    public void onItemClick(AdapterView<?> parent, View view,
     84      int position, long id) {
     85     Toast.makeText(MainActivity.this, title[position], 1).show();
     86    }
     87   });
     88   layout_left.setOnTouchListener(this);
     89   iv_set.setOnTouchListener(this);
     90   mGestureDetector = new GestureDetector(this);
     91   // 禁用长按监听
     92   mGestureDetector.setIsLongpressEnabled(false);
     93   getMAX_WIDTH();
     94  }
     95 
     96  
     97 
     98  /***
     99   * 获取移动距离 移动的距离其实就是layout_left的宽度
    100   */
    101  void getMAX_WIDTH() {
    102   ViewTreeObserver viewTreeObserver = layout_left.getViewTreeObserver();
    103   // 获取控件宽度
    104   viewTreeObserver.addOnPreDrawListener(new OnPreDrawListener() {
    105    @Override
    106    public boolean onPreDraw() {
    107     if (!hasMeasured) {
    108      window_width = getWindowManager().getDefaultDisplay()
    109        .getWidth();
    110      RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) layout_left
    111        .getLayoutParams();
    112      // layoutParams.width = window_width;
    113      layout_left.setLayoutParams(layoutParams);
    114      MAX_WIDTH = layout_right.getWidth();
    115      Log.v(TAG, "MAX_WIDTH=" + MAX_WIDTH + "width="
    116        + window_width);
    117      hasMeasured = true;
    118     }
    119     return true;
    120    }
    121   });
    122 
    123  
    124 
    125  }
    126 
    127  
    128 
    129  @Override
    130  public void onCreate(Bundle savedInstanceState) {
    131   super.onCreate(savedInstanceState);
    132   requestWindowFeature(Window.FEATURE_NO_TITLE);
    133   setContentView(R.layout.main);
    134   InitView();
    135 
    136  
    137 
    138  }
    139 
    140  
    141 
    142  // 返回键
    143  @Override
    144  public boolean onKeyDown(int keyCode, KeyEvent event) {
    145   if (KeyEvent.KEYCODE_BACK == keyCode && event.getRepeatCount() == 0) {
    146    RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) layout_left
    147      .getLayoutParams();
    148    if (layoutParams.leftMargin < 0) {
    149     new AsynMove().execute(SPEED);
    150     return false;
    151    }
    152   }
    153 
    154  
    155 
    156   return super.onKeyDown(keyCode, event);
    157  }
    158 
    159  
    160 
    161  @Override
    162  public boolean onTouch(View v, MotionEvent event) {
    163   // 松开的时候要判断,如果不到半屏幕位子则缩回去,
    164   if (MotionEvent.ACTION_UP == event.getAction() && isScrolling == true) {
    165    RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) layout_left
    166      .getLayoutParams();
    167    // 缩回去
    168    if (layoutParams.leftMargin < -window_width / 2) {
    169     new AsynMove().execute(-SPEED);
    170    } else {
    171     new AsynMove().execute(SPEED);
    172    }
    173   }
    174 
    175  
    176 
    177   return mGestureDetector.onTouchEvent(event);
    178  }
    179 
    180  
    181 
    182  @Override
    183  public boolean onDown(MotionEvent e) {
    184   mScrollX = 0;
    185   isScrolling = false;
    186   // 将之改为true,不然事件不会向下传递.
    187   return true;
    188  }
    189 
    190  
    191 
    192  @Override
    193  public void onShowPress(MotionEvent e) {
    194 
    195  
    196 
    197  }
    198 
    199  
    200 
    201  /***
    202   * 点击松开执行
    203   */
    204  @Override
    205  public boolean onSingleTapUp(MotionEvent e) {
    206   RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) layout_left
    207     .getLayoutParams();
    208   // 左移动
    209   if (layoutParams.leftMargin >= 0) {
    210    new AsynMove().execute(-SPEED);
    211   } else {
    212    // 右移动
    213    new AsynMove().execute(SPEED);
    214   }
    215 
    216  
    217 
    218   return true;
    219  }
    220 
    221  
    222 
    223  /***
    224   * e1 是起点,e2是终点,如果distanceX=e1.x-e2.x>0说明向左滑动。反之亦如此.
    225   */
    226  @Override
    227  public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
    228    float distanceY) {
    229   isScrolling = true;
    230   mScrollX += distanceX;// distanceX:向左为正,右为负
    231   RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) layout_left
    232     .getLayoutParams();
    233   layoutParams.leftMargin -= mScrollX;
    234   if (layoutParams.leftMargin >= 0) {
    235    isScrolling = false;// 拖过头了不需要再执行AsynMove了
    236    layoutParams.leftMargin = 0;
    237 
    238  
    239 
    240   } else if (layoutParams.leftMargin <= -MAX_WIDTH) {
    241    // 拖过头了不需要再执行AsynMove了
    242    isScrolling = false;
    243    layoutParams.leftMargin = -MAX_WIDTH;
    244   }
    245   layout_left.setLayoutParams(layoutParams);
    246   return false;
    247  }
    248 
    249  
    250 
    251  @Override
    252  public void onLongPress(MotionEvent e) {
    253 
    254  
    255 
    256  }
    257 
    258  
    259 
    260  @Override
    261  public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
    262    float velocityY) {
    263   return false;
    264  }
    265 
    266  
    267 
    268  class AsynMove extends AsyncTask<Integer, Integer, Void> {
    269 
    270  
    271 
    272   @Override
    273   protected Void doInBackground(Integer... params) {
    274    int times = 0;
    275    if (MAX_WIDTH % Math.abs(params[0]) == 0)// 整除
    276     times = MAX_WIDTH / Math.abs(params[0]);
    277    else
    278     times = MAX_WIDTH / Math.abs(params[0]) + 1;// 有余数
    279 
    280  
    281 
    282    for (int i = 0; i < times; i++) {
    283     publishProgress(params[0]);
    284     try {
    285      Thread.sleep(Math.abs(params[0]));
    286     } catch (InterruptedException e) {
    287      e.printStackTrace();
    288     }
    289    }
    290 
    291  
    292 
    293    return null;
    294   }
    295 
    296  
    297 
    298   /**
    299    * update UI
    300    */
    301   @Override
    302   protected void onProgressUpdate(Integer... values) {
    303    RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) layout_left
    304      .getLayoutParams();
    305    // 右移动
    306    if (values[0] > 0) {
    307     layoutParams.leftMargin = Math.min(layoutParams.leftMargin
    308       + values[0], 0);
    309     Log.v(TAG, "移动右" + layoutParams.rightMargin);
    310    } else {
    311     // 左移动
    312     layoutParams.leftMargin = Math.max(layoutParams.leftMargin
    313       + values[0], -MAX_WIDTH);
    314     Log.v(TAG, "移动左" + layoutParams.rightMargin);
    315    }
    316    layout_left.setLayoutParams(layoutParams);
    317 
    318  
    319 
    320   }
    321 
    322  
    323 
    324  }
    325 
    326  
    327 
    328 }

    上面代码注释已经很明确,相信大家都看的明白,我就不过多解释了。

    效果图:截屏出来有点卡,不过在手机虚拟机上是不卡的.

     

    源码地址 仿人人网滑动菜单
    http://www.eoeandroid.com/forum.php?mod=viewthread&tid=247442&fromuid=533640

    怎么样,看着还行吧,我们在看下面一个示例:

     

     

    简单说明一下,当你滑动的时候左边会跟着右边一起滑动,这个效果比上面那个酷吧,上面那个有点死板,其实实现起来也比较容易,只需要把我们上面那个稍微修改下,对layout_right也进行时时更新,这样就实现了这个效果了,如果上面那个理解了,这个很轻松就解决了,在这里我又遇到一个问题:此时的listview的item监听不到手势,意思就是我左右滑动listview他没有进行滑动。

    本人对touch众多事件监听拦截等熟悉度不够,因此这里我用到自己写的方法,也许比较麻烦,如果有更好的解决办法,请大家一定要分享哦,再次 thanks for you 了.

    具体解决办法:我们重写listview,对此listview进行手势监听,我们自定义一个接口来实现,具体代码如下:

      1 package com.jj.slidingmenu;
      2 
      3  
      4 
      5 import android.content.Context;
      6 import android.util.AttributeSet;
      7 import android.util.Log;
      8 import android.view.GestureDetector;
      9 import android.view.MotionEvent;
     10 import android.view.GestureDetector.OnGestureListener;
     11 import android.view.View;
     12 import android.widget.ListView;
     13 import android.widget.Toast;
     14 
     15  
     16 
     17 public class MyListView extends ListView implements OnGestureListener {
     18 
     19  
     20 
     21  private GestureDetector gd;
     22  // 事件状态
     23  public static final char FLING_CLICK = 0;
     24  public static final char FLING_LEFT = 1;
     25  public static final char FLING_RIGHT = 2;
     26  public static char flingState = FLING_CLICK;
     27 
     28  
     29 
     30  private float distanceX;// 水平滑动的距离
     31 
     32  
     33 
     34  private MyListViewFling myListViewFling;
     35 
     36  
     37 
     38  public static boolean isClick = false;// 是否可以点击
     39 
     40  
     41 
     42  public void setMyListViewFling(MyListViewFling myListViewFling) {
     43   this.myListViewFling = myListViewFling;
     44  }
     45 
     46  
     47 
     48  public float getDistanceX() {
     49   return distanceX;
     50  }
     51 
     52  
     53 
     54  public char getFlingState() {
     55   return flingState;
     56  }
     57 
     58  
     59 
     60  private Context context;
     61 
     62  
     63 
     64  public MyListView(Context context) {
     65   super(context);
     66 
     67  
     68 
     69  }
     70 
     71  
     72 
     73  public MyListView(Context context, AttributeSet attrs) {
     74   super(context, attrs);
     75   this.context = context;
     76   gd = new GestureDetector(this);
     77  }
     78 
     79  
     80 
     81  /**
     82   * 覆写此方法,以解决ListView滑动被屏蔽问题
     83   */
     84  @Override
     85  public boolean dispatchTouchEvent(MotionEvent event) {
     86   myListViewFling.doFlingOver(event);// 回调执行完毕.
     87   this.gd.onTouchEvent(event);
     88 
     89  
     90 
     91   return super.dispatchTouchEvent(event);
     92  }
     93 
     94  
     95 
     96  @Override
     97  public boolean onTouchEvent(MotionEvent ev) {
     98   /***
     99    * 当移动的时候
    100    */
    101   if (ev.getAction() == MotionEvent.ACTION_DOWN)
    102    isClick = true;
    103   if (ev.getAction() == MotionEvent.ACTION_MOVE)
    104    isClick = false;
    105   return super.onTouchEvent(ev);
    106  }
    107 
    108  
    109 
    110  @Override
    111  public boolean onDown(MotionEvent e) {
    112   int position = pointToPosition((int) e.getX(), (int) e.getY());
    113   if (position != ListView.INVALID_POSITION) {
    114    View child = getChildAt(position - getFirstVisiblePosition());
    115   }
    116   return true;
    117  }
    118 
    119  
    120 
    121  @Override
    122  public void onShowPress(MotionEvent e) {
    123 
    124  
    125 
    126  }
    127 
    128  
    129 
    130  @Override
    131  public boolean onSingleTapUp(MotionEvent e) {
    132 
    133  
    134 
    135   return false;
    136  }
    137 
    138  
    139 
    140  @Override
    141  public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
    142    float distanceY) {
    143   // 左滑动
    144   if (distanceX > 0) {
    145    flingState = FLING_RIGHT;
    146    Log.v("jj", "左distanceX=" + distanceX);
    147    myListViewFling.doFlingLeft(distanceX);// 回调
    148    // 右滑动.
    149   } else if (distanceX < 0) {
    150    flingState = FLING_LEFT;
    151    Log.v("jj", "右distanceX=" + distanceX);
    152    myListViewFling.doFlingRight(distanceX);// 回调
    153   }
    154 
    155  
    156 
    157   return false;
    158  }
    159 
    160  
    161 
    162  /***
    163   * 上下文菜单
    164   */
    165  @Override
    166  public void onLongPress(MotionEvent e) {
    167   // System.out.println("Listview long press");
    168   // int position = pointToPosition((int) e.getX(), (int) e.getY());
    169   // if (position != ListView.INVALID_POSITION) {
    170   // View child = getChildAt(position - getFirstVisiblePosition());
    171   // if (child != null) {
    172   // showContextMenuForChild(child);
    173   // this.requestFocusFromTouch();
    174   // }
    175   //
    176   // }
    177  }
    178 
    179  
    180 
    181  @Override
    182  public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
    183    float velocityY) {
    184 
    185  
    186 
    187   return false;
    188  }
    189 
    190  
    191 
    192  /***
    193   * 回调接口
    194   * 
    195   * @author jjhappyforever...
    196   * 
    197   */
    198  interface MyListViewFling {
    199   void doFlingLeft(float distanceX);// 左滑动执行
    200 
    201  
    202 
    203   void doFlingRight(float distanceX);// 右滑动执行
    204 
    205  
    206 
    207   void doFlingOver(MotionEvent event);// 拖拽松开时执行
    208 
    209  
    210 
    211  }
    212 
    213  
    214 
    215 }

    而在MainActivity.java里面实现该接口,我这么一说,我想有的同学们都明白了,具体实现起来代码有点多,我把代码上传到网上,大家可以下载后用心看,我想大家都能够明白的.(在这里我鄙视一下自己,肯定通过对手势监听拦截实现对listview的左右滑动,但是自己学业不经,再次再说一下,如有好的解决方案,请一定要分享我一下哦.)

    另外有一个问题:当listivew超出一屏的时候,此时的listview滑动的时候可以上下左右一起滑动,在此没有解决这个问题,如有解决请分享我哦.

    源码 仿人人网滑动菜单
    http://www.eoeandroid.com/forum.php?mod=viewthread&tid=247442&fromuid=533640

    地址:http://blog.csdn.net/jj120522/article/details/8075249

    由于篇符较长,先说到这里,其实android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu也可以实现.具体参考下一篇文章:android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu

    先写到这里,有不足的地方请指出,

    如果对您有帮助的话请记得赞一个哦. thanks for you。

    贴2个老外的

    http://stackoverflow.com/questions/11234375/how-did-google-manage-to-do-this-slide-actionbar-in-android-application/11367825#11367825

    http://stackoverflow.com/questions/8657894/android-facebook-style-slide

  • 相关阅读:
    C#线程同步(1)- 临界区&Lock
    详细解析Java中抽象类和接口的区别
    防止重复提交的几种办法
    网页中实现JSON的编辑与显示
    xcode5 ios7升级后的一系列问题解决
    hadoop-2.0.0-mr1-cdh4.2.0源码编译总结
    hadoop-2.0.0-cdh4.2.1源码编译总结
    cocos2d-iphone加入芒果广告
    hadoop2.0 eclipse 源码编译
    HBase学习笔记
  • 原文地址:https://www.cnblogs.com/androidxiaoyang/p/2751587.html
Copyright © 2011-2022 走看看