Android中侧滑菜单效果实现(主界面和菜单界面实现平移、缩放、滚动动画)
编写不易,如有转载,请声明出处: 梦回河口:http://blog.csdn.net/zxc514257857/article/details/72602778
技术要点
- 自定义侧滑控件SlideMenu
- 主界面和菜单界面实现伴随移动
- 根据拖拽的百分比实现平移、缩放、滚动等动画效果
- ListView的基本使用
- Butterknife 的使用
Demo展示图片
布局代码
//(layout)activity_main
<com.test.slidemenu.view.SlideMenu
xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/slideMenu"android:background="@mipmap/bg"android:layout_width="match_parent"android:layout_height="match_parent"><!--两个子View--><!--引入菜单布局 通过getChildAt(0)获取--><include layout="@layout/layout_menu"/><!--引入主界面布局 通过getChildAt(1)获取--><include layout="@layout/layout_main"/></com.test.slidemenu.view.SlideMenu>
-------------------------------------------------------------------
//(layout)layout_main
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:background="#fff"android:id="@+id/main_linearlayout"android:layout_height="match_parent"><FrameLayout
android:background="#18B4ED"android:layout_width="match_parent"android:layout_height="60dp"><ImageView
android:layout_marginStart="20dp"android:layout_width="50dp"android:id="@+id/iv_headMainPic"android:layout_gravity="center_vertical"android:src="@mipmap/headpic"android:layout_height="50dp"/></FrameLayout><ListView
android:overScrollMode="never"android:layout_width="match_parent"android:layout_height="match_parent"android:id="@+id/main_listview"/>
</LinearLayout>
-------------------------------------------------------------------
//(layout)layout_menu
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/menu_linearlayout"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><ImageView android:id="@+id/iv_headMenuPic"android:layout_width="90dp"android:layout_height="90dp"android:background="@mipmap/headpic"android:layout_marginTop="50dp"android:layout_marginLeft="10dp"/><ListView android:layout_width="match_parent"android:layout_marginTop="5dp"android:layout_height="match_parent"android:id="@+id/menu_listview"/>
</LinearLayout>
-------------------------------------------------------------------
//(layout)mainitem
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><RelativeLayout
android:layout_width="match_parent"android:layout_height="60dp"><ImageView
android:id="@+id/iv_pic"android:src="@mipmap/pic"android:layout_width="50dp"android:layout_height="wrap_content"android:layout_marginLeft="20dp"android:layout_marginRight="15dp"/><TextView
android:id="@+id/tv_contact"android:textSize="18sp"android:textColor="#FF3E96"android:layout_centerVertical="true"android:layout_toRightOf="@+id/iv_pic"android:layout_width="wrap_content"android:layout_height="wrap_content"/></RelativeLayout>
</LinearLayout>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
自定义侧滑控件代码
//(view)SlideMenuimport android.animation.ArgbEvaluator;
import android.animation.FloatEvaluator;
import android.content.Context;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;/*** 自定义SlideMenu控件 实现侧滑效果* 为了避免自己去实现onMeasure和onLayout方法 我们继承FrameLayout,系统已经实现好了宽高的测量和位置的摆放* 为什么不使用LinearLayout和RelativeLayout,因为FrameLayout代码简洁*/public class SlideMenu extends FrameLayout {private static final String TAG = "SlideMenu";// 通过它来进行View拖拽的实现private ViewDragHelper mViewDragHelper;private View mMenuView;private View mMainView;// mainView的拖拽范围private int dragRange;private int mMainWidth;private int mMenuWidth;private FloatEvaluator mFloatEvaluator;private ArgbEvaluator mArgbEvaluator;private OnSlideListener mOnSlideListener;// 表示当前状态: 关闭private DragState mDragState = DragState.Close;public enum DragState{Open ,Close}public SlideMenu(Context context) {this(context , null);}public SlideMenu(Context context, AttributeSet attrs) {this(context, attrs , 0);}public SlideMenu(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);initData();}private void initData(){// 父View、滑动敏感度、回调方法mViewDragHelper = ViewDragHelper.create(this , callback);// 浮点运算器mFloatEvaluator = new FloatEvaluator();// 颜色运算器mArgbEvaluator = new ArgbEvaluator();}/*** 该方法在ViewGroup将子View全部添加进来之后执行,但在onMeasure之前执行* 一般用来初始化子View的引用,但是还不能获取到子View的宽高*/@Overrideprotected void onFinishInflate() {mMenuView = getChildAt(0);mMainView = getChildAt(1);super.onFinishInflate();}/*** 当onMeasure方法执行完之后执行,在该方法中可以获取所有控件的宽高*/@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {dragRange = (int) (getMeasuredWidth()*0.6f);mMainWidth = mMainView.getMeasuredWidth();mMenuWidth = mMenuView.getMeasuredWidth();super.onSizeChanged(w, h, oldw, oldh);}@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {// 让ViewDragHelper帮助我们判断是否应该拦截boolean result = mViewDragHelper.shouldInterceptTouchEvent(ev);return result;}@Overridepublic boolean onTouchEvent(MotionEvent event) {// 让ViewDragHelper帮助我们处理触摸事件mViewDragHelper.processTouchEvent(event);return true;}ViewDragHelper.Callback callback = new ViewDragHelper.Callback() {/*** 判断是否需要捕获View的触摸事件* 这里的child都是当前触摸的View*/@Overridepublic boolean tryCaptureView(View child, int pointerId) {// 捕获mainView和menuView的触摸事件if(child == mMainView || child == mMenuView){return true;}return false;}/*** 当一个View被捕获触摸事件调用*/@Overridepublic void onViewCaptured(View capturedChild, int activePointerId) {Log.i(TAG , "onViewCaptured:" + activePointerId);super.onViewCaptured(capturedChild, activePointerId);}/*** 通过返回值判断滑动方向 只要大于0就可以正常水平垂直滑动*/@Overridepublic int getViewHorizontalDragRange(View child) {return 1;}/*** 用于捕获子View在水平方向上的移动* @param left:是ViewDragHelper帮我们计算好的View最新的left的值* left = child.getLeft() + dx* @return 真正想要View的Left变成的值*/@Overridepublic int clampViewPositionHorizontal(View child, int left, int dx) {// 限制主界面移动if(child == mMainView){left = clampLeft(left);}return left;}// /**
// * 用于捕获子View在垂直方向上的移动
// */
// @Override
// public int clampViewPositionVertical(View child, int top, int dy) {// return top;
// }/*** 当View移动的时候调用,可以获取到手指移动的距离*/@Overridepublic void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {// 当手指在menuView移动的时候,让mainView进行一个伴随的移动,但是menuView不动Log.i(TAG , "left: " + left + "dx: " + dx);// menuView固定住mMenuView.layout(0 ,0 , mMenuWidth , mMenuView.getBottom());if(changedView == mMenuView){int newLeft = mMainView.getLeft() + dx;// 限制newLeft否则,在menuView上滑动mainView无限制newLeft = clampLeft(newLeft);// 移动mainViewmMainView.layout(newLeft ,0 , newLeft + mMainWidth , mMainView.getBottom());}// 增加伴随动画float fraction = mMainView.getLeft() * 1.0f / dragRange;// 得到百分比Log.i(TAG , "fraction" + fraction);// 执行动画效果execAnim(fraction);// 回调监听器的方法if(fraction == 0f && mDragState !=DragState.Close){mDragState =DragState.Close;// 说明关闭了if(mOnSlideListener != null){mOnSlideListener.onClose();}// 说明打开了}else if(fraction == 1f && mDragState !=DragState.Open){mDragState =DragState.Open;if(mOnSlideListener != null){mOnSlideListener.onOpen();}}// 说明在拖拽中if(mOnSlideListener != null){mOnSlideListener.onDraging(fraction);}super.onViewPositionChanged(changedView, left, top, dx, dy);}/*** 当手指从View上抬起的时候执行*/@Overridepublic void onViewReleased(View releasedChild, float xvel, float yvel) {// 判断mainView的left是否是大于dragRange的一半if(mMainView.getLeft() > dragRange / 2){// mainView平滑滚动到右边mViewDragHelper.smoothSlideViewTo(mMainView , dragRange , 0 );}else{// mainView平滑滚动到左边mViewDragHelper.smoothSlideViewTo(mMainView , 0 , 0 );}// 刷新操作ViewCompat.postInvalidateOnAnimation(SlideMenu.this);super.onViewReleased(releasedChild, xvel, yvel);}};/*** 根据拖拽的百分比来进行伴随动画效果*/private void execAnim(float fraction) {// mainView的缩放mMainView.setScaleX(mFloatEvaluator.evaluate(fraction , 1.0f , 0.8f));mMainView.setScaleY(mFloatEvaluator.evaluate(fraction , 1.0f , 0.8f));// menuView的缩放mMenuView.setScaleX(mFloatEvaluator.evaluate(fraction , 0.4f , 1f));mMenuView.setScaleY(mFloatEvaluator.evaluate(fraction , 0.4f , 1f));// menuView 水平方向的平移mMenuView.setTranslationX(mFloatEvaluator.evaluate(fraction ,-mMenuWidth /2, 0));// 设置SlideMenu的颜色遮罩getBackground();if(getBackground() != null){// 由黑色变为透明的遮罩效果int color = (int) mArgbEvaluator.evaluate(fraction, Color.BLACK, Color.TRANSPARENT);getBackground().setColorFilter(color, PorterDuff.Mode.DARKEN);}}@Overridepublic void computeScroll() {// 判断动画有没有结束,如果为true表示没有结束if(mViewDragHelper.continueSettling(true)){// 刷新操作ViewCompat.postInvalidateOnAnimation(SlideMenu.this);}super.computeScroll();}/*** 修正左边距*/private int clampLeft(int left) {if(left > dragRange){left = dragRange;}else if(left < 0){left = 0;}return left;}public interface OnSlideListener{void onOpen();void onClose();void onDraging(float fraction);}public void setOnSlideListener(OnSlideListener mOnSlideListener){this.mOnSlideListener = mOnSlideListener;}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
常量类代码
//conf(Constant)
public class Constant {public static final String[] SETTINGS = {"激活会员" , "QQ钱包" , "个性装扮" , "我的收藏" , "我的相册" , "我的文件"};public static final String[] CONSTACTS = {"宋江", "卢俊义","吴用","公孙胜","关胜","林冲","秦明","呼延灼","花荣","柴进","李应","朱仝","鲁智深","武松","董平","张清","扬志","徐宁","索超","戴宗","刘唐","李逵","史进","穆弘","雷横","李俊","阮小二","张横","阮小五","张顺","阮小七","杨雄","石秀","解珍","解宝","燕青","朱武","黄信","孙立","宣赞","赦思文","韩滔","彭玑","单廷","魏定国","萧让","裴宣","欧鹏","邓飞","燕顺","杨林","凌振","蒋敬","吕方","郭盛","安道全","皇浦端","王英","扈三娘","鲍旭","樊瑞","孔明","孔亮","项充","李衮","金大坚","马麟","童威","童猛","孟康","候建","陈达","杨春","郑天寿","陶宗旺","宋清","乐和","龚旺","丁得孙","穆春","曹正","宋万","杜迁","薛永","施恩","李忠","周通","汤隆","杜兴","邹渊","邹润","朱贵","朱富","蔡福","蔡庆","李立","李云","焦挺","石勇","孙新","顾大嫂","张青","孙二娘","王定六","郁保四","白胜","时迁","段景住"};
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
activity代码
//(activity)MainActivity
import android.animation.FloatEvaluator;
import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;
import com.test.slidemenu.R;
import com.test.slidemenu.view.SlideMenu;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import butterknife.Bind;
import butterknife.ButterKnife;
import static com.test.slidemenu.conf.Constant.CONSTACTS;
import static com.test.slidemenu.conf.Constant.SETTINGS;public class MainActivity extends AppCompatActivity {private static final String TAG = "MainActivity";private FloatEvaluator mFloatEvaluator;@Bind(R.id.iv_headMenuPic)ImageView mIvHeadMenuPic;@Bind(R.id.menu_listview)ListView mMenuListview;@Bind(R.id.menu_linearlayout)LinearLayout mMenuLinearlayout;@Bind(R.id.iv_headMainPic)ImageView mIvHeadMainPic;@Bind(R.id.main_listview)ListView mMainListview;@Bind(R.id.main_linearlayout)LinearLayout mMainLinearlayout;@Bind(R.id.slideMenu)SlideMenu mSlideMenu;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();initData();}private void initView() {ButterKnife.bind(this);mFloatEvaluator = new FloatEvaluator();}private void initData() {mMenuListview.setAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, SETTINGS) {@NonNull@Override// 修改布局属性public View getView(int position, View convertView, ViewGroup parent) {TextView textView = (TextView) super.getView(position, convertView, parent);textView.setTextColor(Color.parseColor("#FF3E96"));textView.setTextSize(18);textView.setSingleLine();return textView;}});mMenuListview.setDivider(null);mMenuListview.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {Toast.makeText(MainActivity.this, SETTINGS[i], Toast.LENGTH_SHORT).show();}});List<Map<String, Object>> data = new ArrayList<>();String[] from = {"pic", "contact" };int[] to = {R.id.iv_pic, R.id.tv_contact};mMainListview.setAdapter(new SimpleAdapter(MainActivity.this, data, R.layout.mainitem, from, to));for (int i = 0; i < CONSTACTS.length; i++) {Map<String, Object> map = new HashMap<>();map.put("pic", R.mipmap.pic);map.put("contact", CONSTACTS[i]);data.add(map);}mMainListview.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {Toast.makeText(MainActivity.this, CONSTACTS[i], Toast.LENGTH_SHORT).show();}});mSlideMenu.setOnSlideListener(new SlideMenu.OnSlideListener() {@Overridepublic void onOpen() {Toast.makeText(MainActivity.this, "onOpen", Toast.LENGTH_SHORT).show();}@Overridepublic void onClose() {Toast.makeText(MainActivity.this, "onClose", Toast.LENGTH_SHORT).show();}@Overridepublic void onDraging(float fraction) {Log.i(TAG, "fraction:" + fraction);// 沿着y轴旋转mIvHeadMainPic.setRotationY(mFloatEvaluator.evaluate(fraction, 0, 720));}});mIvHeadMenuPic.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {Toast.makeText(MainActivity.this, "我是menuView头像", Toast.LENGTH_SHORT).show();}});mIvHeadMainPic.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {Toast.makeText(MainActivity.this, "我是mainView头像", Toast.LENGTH_SHORT).show();}});}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
注
使用Butterknife 需在Module的build.gradle中的dependencies节点下面添加:
compile 'com.jakewharton:butterknife:7.0.1'
- 1
目前最新版本为8.6.0。Butterknife配合ButterKnife Zelezny插件使用更佳
如果对Butterknife和ButterKnife Zelezny插件使用不太清楚可移步:Android中ButterKnife的使用(库和插件)http://blog.csdn.net/zxc514257857/article/details/59195960
Demo下载请移步:http://download.csdn.net/detail/zxc514257857/9848331
———-因本人才疏学浅,如博客或Demo中有错误的地方请大家随意指出,与大家一起讨论,共同进步,谢谢!
Android中侧滑菜单效果实现(主界面和菜单界面实现平移、缩放、滚动动画)相关推荐
- android 表格xml,【Android】利用表格布局,Android中xml文件与java的交互制作登录界面...
登录界面是图形编程.网页编程的一个经典而又基础的程序. 在安卓中,如图所示一个基本登录界面: 点击取消按钮就关闭这个程序,点击登录按钮则显示用户输入的用户名与密码. 一.基本布局 这个程序利用到安卓中 ...
- android 苹果菜单栏,android仿iphone主题效果的主菜单
现在很多第三方Launcher((如360Launcher,GoLauncher)带有iphone主题,相信玩Android的人大都知道. 本例实现仿iphone主题的launcher的冰山一角.如下 ...
- Android中实现长按照片弹出右键菜单
场景 效果 注: 博客: https://blog.csdn.net/badao_liumang_qizhi 关注公众号 霸道的程序猿 获取编程相关电子书.教程推送与免费下载. 实现 将布局改为Lin ...
- android中帧布局效果,Android开发实现布局帧布局霓虹灯效果示例
本文实例讲述了android开发实现布局帧布局霓虹灯效果.分享给大家供大家参考,具体如下: 效果图: 实现方式: framelayout中,设置8个textview,在主函数中,设计颜色数组,通过有序 ...
- 解决Android中多次点击启动多个相同界面的问题
2015.12.02 补充说明 下面方法虽然解决了连续点击问题,但也会造成页面滑动时卡顿现象(即第二次滑动时,无响应) 经过认证,发现最好的解决方法是使用手势GestureDetector.通过 ...
- android 中的弹幕效果
android 弹幕评论效果 分类: android2015-07-28 09:21 977人阅读 评论(0) 收藏 举报 android弹幕 纯粹按照自己的想法仿照b站的弹幕写的一个demo,不知道 ...
- android中实现毛笔效果(View 中绘图)
最近有一个项目设计一个APP实现通过触摸屏实现毛笔写字效果.传统的绘画板程序直接通过Path的moveTo和LineTo便可实现简单的线条绘画程序.然而要达到毛笔的笔锋效果则需要更为详细点的设计.我的 ...
- android中实现毛笔效果(View 中画图)
近期有一个项目设计一个APP实现通过触摸屏实现毛笔写字效果.传统的绘画板程序直接通过Path的moveTo和LineTo便可实现简单的线条绘画程序.然而要达到毛笔的笔锋效果则须要更为具体点的设计.我的 ...
- android中帧布局效果,布局之FrameLayout(帧布局)详解
New UI-布局之FrameLayout(帧布局)详解 --转载请注明出处:coder-pig,欢迎转载,请勿用于商业用途!本节引言:FrameLayout(帧布局)可以说是六大布局中最为简单的一 ...
- Android 中设置只是程序第一次运行才显示的界面
程序安装后第一次启动: 启动页-->功能介绍页-->系统主页 以后启动: 启动页-->系统主页 所以在启动页中判断一下就可以了 可以弄一个文件保存一个状态,推荐用SharedPref ...
最新文章
- java学习--第50天讲到jquery
- malloc/free和new/delete的区别
- HDU 4634 Swipe Bo(搜索)
- Dubbo(九)之注解配置
- Verilog HDL学习笔记(一)常见错误
- ORACLE学习之绑定变量
- 有趣的二进制—高效位运算
- IndexedDB封装
- 免费 web api 接口大全
- 旷视天元开源图片对比工具 MegSpot,助力图像算法研发
- iOS 人脸识别Demo
- 2018.9.8-9.8 统计学课程笔记(1)-从概率论到统计学
- java 设置图标_设置java窗口的图标
- 网易云web安全工程师第二天
- 跨境贸易EDM邮件使用指南
- 【Redis笔记】缓存穿透与缓存击穿以及应对方法
- 两个龙的linux,Linux办公一条龙之组件间的调用
- 降本增效这九个月,爱奇艺从“穿越火线”,到“冷静增长”
- LeaRun.net快速开发动态表单
- 打破行业困境,大麦如何引领NB-IoT技术的创新应用