首页 文章 精选 留言 我的

精选列表

搜索[网站开发],共10000篇文章
优秀的个人博客,低调大师

iOS开发-仿大众点评iPad侧边导航栏

昨天其实已经写了一篇侧边栏的文章,不过感觉还不是很清晰,这篇文章算是补充吧,iPad上看了大众点评的侧边栏,基本上百分之九十类似,具体效果可参考下图: 对比昨天主要做了两个修改,一个是图片和文字的显示位置,另外一个就是关于底部的定位和设置的位置在横竖屏时显示的问题,侧边栏的区域是是自己控制的,需要注意一下横竖屏的时候设置一下autoresizingMask,底部图标定位的时候也是一样设置。 导航栏上每个按钮提取出了一个父类GPDockItem,头文件中的代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 // // GPDockItem.h // GrouponProject //博客园FlyElephant:http://www.cnblogs.com/xiaofeixiang // Created by keso on 15/3/11. // Copyright (c) 2015年 keso. All rights reserved. // #import <UIKit/UIKit.h> @interface GPDockItem : UIButton -( void )imageSetting:( NSString *)backgroundImage selectedImage:( NSString *)selectedImage; @property ( nonatomic ,strong) NSString *title; //背景图片 @property ( nonatomic ,strong) NSString *backgroundImage; //选中图片 @property ( nonatomic ,strong) NSString *selectedImage; @end 相对于之前的代码,主要是添加了设置背景图片和设置选中图片的混合方法,定义了一个Title属性,之后的可以设置文字和图片的位置,重写两个方法: 1 2 3 4 5 6 7 8 9 10 11 12 13 //设置图片区域 -(CGRect)imageRectForContentRect:(CGRect)contentRect{ CGFloat width=contentRect.size.width; CGFloat height= contentRect.size.height * 0.7; return CGRectMake(0, 10, width, height); } //设置文字区域 -(CGRect)titleRectForContentRect:(CGRect)contentRect{ CGFloat width=contentRect.size.width; CGFloat height= contentRect.size.height * 0.3; CGFloat position=contentRect.size.height*0.7; return CGRectMake(0, position, width, height); } 设置背景图片和选中图片: 1 2 3 4 5 -( void )imageSetting:( NSString *)backgroundImage selectedImage:( NSString *)selectedImage{ self .backgroundImage=backgroundImage; self .selectedImage=selectedImage; } 设置显示文字和图片在区域内的位置: 1 2 3 4 5 6 7 8 9 10 11 -( void )setTitle:( NSString *)title{ [ self setTitle:title forState:UIControlStateNormal]; self .titleLabel.textAlignment= NSTextAlignmentCenter ; self .titleLabel.font = [UIFont systemFontOfSize:15]; //正常状态下是灰色 [ self setTitleColor:[UIColor grayColor] forState:UIControlStateNormal]; //不可点击的时候切换文字颜色 [ self setTitleColor:[UIColor orangeColor] forState:UIControlStateDisabled]; //设置图片属性 self .imageView.contentMode = UIViewContentModeCenter; } GPDockItem.m中的代码: 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 // // GPDockItem.m // GrouponProject //博客园FlyElephant:http://www.cnblogs.com/xiaofeixiang // Created by keso on 15/3/11. // Copyright (c) 2015年 keso. All rights reserved. // #import "GPDockItem.h" @implementation GPDockItem /* // Only override drawRect: if you perform custom drawing. // An empty implementation adversely affects performance during animation. - (void)drawRect:(CGRect)rect { // Drawing code } */ -(instancetype)initWithFrame:(CGRect)frame{ self =[ super initWithFrame:frame]; // if (self) { //// UIImageView *splitLine = [[UIImageView alloc] init]; //// splitLine.frame = CGRectMake(0, 0, GPDockItemWidth, 2); //// splitLine.image = [UIImage imageNamed:@"separator_tabbar_item.png"]; //// [self addSubview:splitLine]; // // } return self ; } -( void )setTitle:( NSString *)title{ [ self setTitle:title forState:UIControlStateNormal]; self .titleLabel.textAlignment= NSTextAlignmentCenter ; self .titleLabel.font = [UIFont systemFontOfSize:15]; //正常状态下是灰色 [ self setTitleColor:[UIColor grayColor] forState:UIControlStateNormal]; //不可点击的时候切换文字颜色 [ self setTitleColor:[UIColor orangeColor] forState:UIControlStateDisabled]; //设置图片属性 self .imageView.contentMode = UIViewContentModeCenter; } -( void )imageSetting:( NSString *)backgroundImage selectedImage:( NSString *)selectedImage{ self .backgroundImage=backgroundImage; self .selectedImage=selectedImage; } //设置背景图片 -( void )setBackgroundImage:( NSString *)backgroundImage{ _backgroundImage=backgroundImage; [ self setImage:[UIImage imageNamed:backgroundImage] forState:UIControlStateNormal]; } //设置选中图片 -( void )setSelectedImage:( NSString *)selectedImage{ _selectedImage=selectedImage; [ self setImage:[UIImage imageNamed:selectedImage] forState:UIControlStateDisabled]; } //设置图片区域 -(CGRect)imageRectForContentRect:(CGRect)contentRect{ CGFloat width=contentRect.size.width; CGFloat height= contentRect.size.height * 0.7; return CGRectMake(0, 10, width, height); } //设置文字区域 -(CGRect)titleRectForContentRect:(CGRect)contentRect{ CGFloat width=contentRect.size.width; CGFloat height= contentRect.size.height * 0.3; CGFloat position=contentRect.size.height*0.7; return CGRectMake(0, position, width, height); } -( void )setFrame:(CGRect)frame{ //固定Item宽高 frame.size=CGSizeMake(GPDockItemWidth, GPDockItemHeight); [ super setFrame:frame]; } @end 继承自GPDockItem的GPBottomItem,只需要设置横竖屏自动伸缩属性即可: 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 // // GPBottomItem.m // GrouponProject // FlyElephant--http://www.cnblogs.com/xiaofeixiang // Created by keso on 15/3/13. // Copyright (c) 2015年 keso. All rights reserved. // #import "GPBottomItem.h" @implementation GPBottomItem /* // Only override drawRect: if you perform custom drawing. // An empty implementation adversely affects performance during animation. - (void)drawRect:(CGRect)rect { // Drawing code } */ -(instancetype)initWithFrame:(CGRect)frame{ self =[ super initWithFrame:frame]; if ( self ) { // 自动伸缩 self .autoresizingMask=UIViewAutoresizingFlexibleTopMargin; } return self ; } @end GPDock.h中的定位: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 -( void )addLocation{ GPBottomItem *tabItem=[[GPBottomItem alloc]init]; [tabItem imageSetting:@ "Toolbar_switchcity.png" selectedImage:@ "Toolbar_switchcity_selected.png" ]; CGFloat y = self .frame.size.height - GPDockItemHeight*2-20; //设置位置 tabItem.frame = CGRectMake(0, y, 0, 0); [tabItem setTitle:@ "北京" ]; //设置选中触摸选中事件 [tabItem addTarget: self action: @selector (tabItemTouchEvent:) forControlEvents:UIControlEventTouchDown]; tabItem.tag =4; [ self addSubview:tabItem]; } GPDock.h中的设置: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 -( void )addSetting{ GPBottomItem *tabItem=[[GPBottomItem alloc]init]; [tabItem imageSetting:@ "Toolbar_setting.png" selectedImage:@ "Toolbar_setting_selected.png" ]; CGFloat y = self .frame.size.height - GPDockItemHeight-10; //设置位置 tabItem.frame = CGRectMake(0, y, 0, 0); [tabItem setTitle:@ "设置" ]; //设置选中触摸选中事件 [tabItem addTarget: self action: @selector (tabItemTouchEvent:) forControlEvents:UIControlEventTouchDown]; tabItem.tag =5; [ self addSubview:tabItem]; } 两者有相同之处,分开合并都行,具体看将来要实现的业务逻辑,将其添加到GPDock中: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 -(instancetype)initWithFrame:(CGRect)frame{ self =[ super initWithFrame:frame]; if ( self ) { //自动伸缩高度可伸缩,右边距可以伸缩 self .autoresizingMask=UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleRightMargin; //设置背景图片 self .backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:@ "Toolbar_bg_tabbar.png" ]]; //添加选项卡 [ self addTabItems]; //添加设置 [ self addLocation]; //添加设置 [ self addSetting]; } return self ; } 最终实现效果如下: 本文转自Fly_Elephant博客园博客,原文链接:http://www.cnblogs.com/xiaofeixiang/p/4334242.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android开发学习笔记:浅谈3大类菜单

在Android系统中,菜单可以分为三类:选项菜单(Option Menu),上下文菜单(Context Menu)以及子菜单(Sub Menu)。 一.选项菜单(Option Menu) 创建选项菜单的步骤: 1.覆盖Activity的onCreateOptionMenu(Menu menu)方法,当菜单第一次被打开时调用 2.调用Menu的add( )方法添加菜单项(MenuItem),同时可以调用MenuItem的setIcon( )方法来为菜单项设置图标 3.当菜单项(MenuItem)被选择时,覆盖Activity的onOptionsItemSelected(MenuItem item)来响应事件 选项菜单的实例: packagecom.android.menu.activity; importandroid.app.Activity; importandroid.os.Bundle; importandroid.view.Menu; importandroid.view.MenuItem; publicclassOptionMenuActivityextendsActivity{ //声明菜单项常量 privatestaticfinalintITEM_1=Menu.FIRST; privatestaticfinalintITEM_2=Menu.FIRST+1; privatestaticfinalintITEM_3=Menu.FIRST+2; publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); } //覆盖onCreateOptionsMenu(Menumenu)来添加菜单项 publicbooleanonCreateOptionsMenu(Menumenu){ //android.R使用的是系统自带的图标 menu.add(0,ITEM_1,0,"开始").setIcon(android.R.drawable.ic_media_play); menu.add(0,ITEM_2,0,"帮助").setIcon(android.R.drawable.ic_menu_help); menu.add(0,ITEM_3,0,"退出").setIcon(android.R.drawable.ic_menu_close_clear_cancel); returntrue; } //覆盖onOptionsItemSelected(MenuItemitem)来响应菜单选项被单击事件 publicbooleanonOptionsItemSelected(MenuItemitem){ switch(item.getItemId()){ caseITEM_1: setTitle("开始游戏!"); break; caseITEM_2: setTitle("查看帮助!"); break; caseITEM_3: setTitle("退出游戏!"); break; } returntrue; } } 效果图: 二.上下文菜单(Context Menu) 创建上下文菜单的步骤: 1.覆盖Activity的onCreateOptionMenu(Menu menu)方法,调用Menu的add( )方法添加菜单项(MenuItem). 2.覆盖Activity的onOptionsItemSelected(MenuItem item)来响应事件 3.调用registerForContextMenu( )方法来为视图注册上下文菜单 上下文菜单的实例(按住“测试Context Menu”2秒,就会出现上下文菜单): packagecom.android.context.activity; importandroid.app.Activity; importandroid.graphics.Color; importandroid.os.Bundle; importandroid.view.ContextMenu; importandroid.view.Menu; importandroid.view.MenuItem; importandroid.view.View; importandroid.view.ContextMenu.ContextMenuInfo; importandroid.widget.TextView; publicclassContextMenuActivityextendsActivity{ privatestaticfinalintITME_1=Menu.FIRST; privatestaticfinalintITME_2=Menu.FIRST+1; privatestaticfinalintITME_3=Menu.FIRST+2; privateTextViewtext; publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); text=(TextView)findViewById(R.id.TextView_1); //调用registerForContextMenu()来注册上下文菜单 registerForContextMenu(text); } @Override publicvoidonCreateContextMenu(ContextMenumenu,Viewv, ContextMenuInfomenuInfo){ menu.add(0,ITME_1,0,"红色背景"); menu.add(0,ITME_2,0,"蓝色背景"); menu.add(0,ITME_3,0,"白色背景"); } @Override publicbooleanonContextItemSelected(MenuItemitem){ switch(item.getItemId()){ caseITME_1: //设置TextView的背景颜色 text.setBackgroundColor(Color.RED); break; caseITME_2: text.setBackgroundColor(Color.BLUE); break; caseITME_3: text.setBackgroundColor(Color.WHITE); break; } returntrue; } } 效果图: 三.子菜单(Sub Menu) 创建子菜单的步骤: 1.覆盖Activity的onCreateOptionMenu(Menu menu)方法,调用Menu的addSubMenu( )方法来添加子菜单(Sub Menu) 2.调用SubMenu的add( )方法来添加子菜单(Sub Menu) 3.覆盖onContextItemSelect( )方法来响应菜单单击事件 子菜单的实例: packagecom.android.sub.activity; importandroid.app.Activity; importandroid.os.Bundle; importandroid.view.Menu; importandroid.view.MenuItem; importandroid.view.SubMenu; publicclassSubMenuActivityextendsActivity{ privatestaticfinalintITEM_1=Menu.FIRST; privatestaticfinalintITEM_2=Menu.FIRST+1; publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); } //覆盖onCreateOptionsMenu(Menumenu)方法,添加子菜单项 publicbooleanonCreateOptionsMenu(Menumenu){ SubMenuad=menu.addSubMenu("添加").setIcon(android.R.drawable.ic_menu_add); SubMenure=menu.addSubMenu("关闭").setIcon(android.R.drawable.ic_menu_close_clear_cancel); ad.add(0,ITEM_1,0,"文件"); ad.add(0,ITEM_2,0,"图片"); returntrue; } //覆盖onOptionsItemSelected(MenuItemitem),响应菜单选项被单击事件 publicbooleanonOptionsItemSelected(MenuItemitem){ switch(item.getItemId()){ caseITEM_1: setTitle("添加文件!"); break; caseITEM_2: setTitle("添加图片!"); break; } returntrue; } } 效果图: 注:menu.add的方法中的参数: 1.int类型的group ID参数,代表的是组概念,你可以将几个菜单项归为一组,以便更好的以组的方式管理你的菜单按钮。可以用到的方法有: removeGroup(id) setGroupCheckable(id, checkable, exclusive) setGroupEnabled(id,boolean enabled) setGroupVisible(id,visible)2.int类型的item ID参数,代表的是项目编号。这个参数非常重要,一个item ID对应一个Menu中的选项。在后面使用菜单的时候,就是靠这个item ID来判断,你选中的是哪个选项。3.int类型的order ID参数,代表的是菜单项的显示顺序。默认是0,表示菜单的显示顺序就是按照add的顺序来显示。4.String类型的title参数,表示选项中显示的文字。 本文转自 lingdududu 51CTO博客,原文链接: http://blog.51cto.com/liangruijun/641275

优秀的个人博客,低调大师

Android开发学习笔记:Button事件实现方法的总结

下面介绍Button事件实现的两种方法 main.xml <?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <Button android:id="@+id/myButton1" android:text="按钮1" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:id="@+id/myButton2" android:text="按钮2" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> strings.xml <?xmlversion="1.0"encoding="utf-8"?> <resources> <stringname="hello">HelloWorld,ButtonDemoActivity!</string> <stringname="app_name">ButtonDemo</string> </resources> 第一种: ButtonDemoActivity.java packagecom.android.ButtonDemo.activity; importandroid.app.Activity; importandroid.os.Bundle; importandroid.view.View; importandroid.view.View.OnClickListener; importandroid.widget.Button; importandroid.widget.Toast; publicclassButtonDemoActivityextendsActivity{ ButtonmyButton1,myButton2; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); myButton1=(Button)findViewById(R.id.myButton1); myButton2=(Button)findViewById(R.id.myButton2); //使用匿名类注册Button事件 myButton1.setOnClickListener(newOnClickListener() { publicvoidonClick(Viewv) { Toast.makeText(ButtonDemoActivity.this,"你点击了按钮1",Toast.LENGTH_LONG).show(); } }); myButton2.setOnClickListener(newOnClickListener() { publicvoidonClick(Viewv) { Toast.makeText(ButtonDemoActivity.this,"你点击了按钮2",Toast.LENGTH_LONG).show(); } }); } } 第二种: ButtonDemoActivity.java packagecom.android.ButtonDemo.activity; importandroid.app.Activity; importandroid.os.Bundle; importandroid.view.View; importandroid.view.View.OnClickListener; importandroid.widget.Button; importandroid.widget.Toast; publicclassButtonDemoActivityextendsActivity{ ButtonmyButton1,myButton2; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); myButton1=(Button)findViewById(R.id.myButton1); myButton2=(Button)findViewById(R.id.myButton2); myButton1.setOnClickListener(newButtonClick()); myButton2.setOnClickListener(newButtonClick()); } //创建一个类,来响应OnClickListener classButtonClickimplementsOnClickListener { publicvoidonClick(Viewv) { switch(v.getId()){ caseR.id.myButton1: Toast.makeText(ButtonDemoActivity.this,"你点击了按钮1",Toast.LENGTH_LONG).show(); break; caseR.id.myButton2: Toast.makeText(ButtonDemoActivity.this,"你点击了按钮2",Toast.LENGTH_LONG).show(); break; default: break; } } } } 本文转自 lingdududu 51CTO博客,原文链接: http://blog.51cto.com/liangruijun/629329

优秀的个人博客,低调大师

[Android学习笔记七] 设备管理服务示例开发

本文通过示例演示Android Device Policy管理的实现。 1.示例基本操作图 上图是本示例的主界面,通过应用程序来实现设备管理,本示例实现密码设置管理。 1.1 通过点击“启动设备管理器”按钮来激活设备管理 应用程序用通知设备管理启用,用户点击激活,应用程序具备设备管理能力。 1.2 通过点击“设置密码规则”按钮来设置锁屏密码的限制规则,要使用该策略需要在设备管理的使用策略列表中添加limit-password. 示例中调用了设置新密码的ACTION(DevicePolicyManager.ACTION_SET_NEW_PASSWORD),通过设置后,看以看到屏幕锁屏需要密码。 1.3 通过点击“修改密码”按钮则可以将文本框中的内容作为锁屏密码,该步骤可以通过程序完成。 调用DevicePolicyManager的重置密码方法(resetPassword),即可在应用程序中对锁屏密码进行重置。 2. 具体实现 实现上述整个示例需要: a.界面布局;实际应用中根据具体情况而定 b.DevicePolicyManager类的具体使用 c.DeviceAdminReceiver类的子类话,来实现具体广播事件的处理 d.AndroidManifest.xml文件中广播接收类的配置 c.应用程序中需要的设备管理策略列表 注:本示例代码使用了Butterknife框架。 2.1 示例程序界面(layout/activity_device_admin.xml) 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 <? xml version = "1.0" encoding = "utf-8" ?> < LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android" android:layout_width = "match_parent" android:layout_height = "match_parent" android:background = "#f7f1f1" android:orientation = "vertical" android:padding = "15dp" > < LinearLayout android:layout_width = "match_parent" android:layout_height = "wrap_content" android:layout_gravity = "center_horizontal" android:orientation = "horizontal" > < EditText android:id = "@+id/pwd_editText" android:layout_width = "0dp" android:layout_height = "wrap_content" android:layout_margin = "10dp" android:layout_weight = "3" android:hint = "6位数字" android:textColor = "@android:color/black" /> < Button android:id = "@+id/modify_pwd_button" android:layout_width = "0dp" android:layout_height = "wrap_content" android:layout_margin = "10dp" android:layout_weight = "1.5" android:text = "修改密码" /> </ LinearLayout > < Button android:id = "@+id/pwd_rule_set_button" android:layout_width = "match_parent" android:layout_height = "wrap_content" android:text = "设置密码规则" /> < Button android:id = "@+id/device_admin_button" android:layout_width = "match_parent" android:layout_height = "wrap_content" android:text = "启用设备管理" /> </ LinearLayout > 2.2 Activity类和自定义的DeviceAdminReceiver类 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 package secondriver.sdk.activity; import android.app.Activity; import android.app.admin.DeviceAdminReceiver; import android.app.admin.DevicePolicyManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import butterknife.Bind; import butterknife.ButterKnife; import butterknife.OnClick; import secondriver.sdk.R; /** *Author:secondriver *Created:2015/11/27 */ public class DeviceAdminActivity extends Activity{ @Bind (R.id.pwd_editText) public EditTextpwdEditText; private DevicePolicyManagermDevicePolicyManager; @Override protected void onCreate(BundlesavedInstanceState){ super .onCreate(savedInstanceState); setContentView(R.layout.activity_device_admin); ButterKnife.bind( this ); mDevicePolicyManager=(DevicePolicyManager)getSystemService(DEVICE_POLICY_SERVICE); } //单击启用设备管理按钮 @OnClick (R.id.device_admin_button) public void onClickDeviceButton(Buttonbutton){ Intentintent= new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN); intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, new ComponentName( this ,MyDeviceAdminReceiver. class )); intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "启动设备管理器" ); startActivityForResult(intent, 1 ); } //单击设置密码规则按钮 @OnClick (R.id.pwd_rule_set_button) public void onClickPwdRuleSetButton(Buttonbutton){ Intentintent= new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD); startActivityForResult(intent, 2 ); } //单击修改密码按钮 @OnClick (R.id.modify_pwd_button) public void onClickModifyPwdButton(Buttonbutton){ Stringpwd=pwdEditText.getText().toString(); ComponentNamereceiver= new ComponentName( this ,MyDeviceAdminReceiver. class ); boolean active=mDevicePolicyManager.isAdminActive(receiver); if (active){ boolean rs=mDevicePolicyManager.resetPassword(pwd,DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY); if (rs){ Toast.makeText( this , "密码修改成功" ,Toast.LENGTH_SHORT).show(); } else { Toast.makeText( this , "密码修改失败" ,Toast.LENGTH_SHORT).show(); } } else { Toast.makeText( this , "没有ActiveAdmin" ,Toast.LENGTH_SHORT).show(); } } @Override protected void onActivityResult( int requestCode, int resultCode,Intentdata){ switch (requestCode){ case 1 : if (resultCode==RESULT_OK){ Toast.makeText( this , "设备管理器开启成功" ,Toast.LENGTH_SHORT).show(); } else { Toast.makeText( this , "设备管理器开启失败" ,Toast.LENGTH_SHORT).show(); } break ; case 2 : if (resultCode==RESULT_OK){ Toast.makeText( this , "密码规则设置成功" ,Toast.LENGTH_SHORT).show(); } else { Toast.makeText( this , "密码规则设置失败" ,Toast.LENGTH_SHORT).show(); } break ; default : break ; } } //自定义的设备管理广播接收类,可以重写DeviceAdminReceiver中的方法,来实现具体功能 public static class MyDeviceAdminReceiver extends DeviceAdminReceiver{ /** *重写其中方法 *<p> *More */ @Override public void onDisabled(Contextcontext,Intentintent){ super .onDisabled(context,intent); //设备管理禁用 } @Override public void onEnabled(Contextcontext,Intentintent){ super .onEnabled(context,intent); //设备管理启用 } } } 2.3 配置设备管理接收者 1 2 3 4 5 6 7 8 9 < activity android:name = ".activity.DeviceAdminActivity" /> < receiver android:name = ".activity.DeviceAdminActivity$MyDeviceAdminReceiver" android:permission = "android.permission.BIND_DEVICE_ADMIN" > < meta-data android:name = "android.app.device_admin" android:resource = "@xml/device_admin" /> < intent-filter > < action android:name = "android.app.action.DEVICE_ADMIN_ENABLED" /> </ intent-filter > </ receiver > xml/device_admin内容: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <? xml version = "1.0" encoding = "utf-8" ?> < device-admin xmlns:android = "http://schemas.android.com/apk/res/android" > < uses-policies > <!--设置密码规则;控制屏幕锁的密码长度和允许的字符--> < limit-password /> <!--监视屏幕锁解锁尝试的次数;如果输入错误次数过多则锁定手机或者清除所有数据--> < watch-login /> <!--重置屏幕锁的密码;重新设置新的屏幕锁密码--> < reset-password /> <!--强制锁屏;控制屏幕锁屏的方式和时间--> < force-lock /> <!--擦除数据;恢复出厂设置清除说有数据--> < wipe-data /> <!--禁用相机;禁止使用所有设备摄像头--> < disable-camera /> <!--加密数据;对存储的应用数据进行加密--> < encrypted-storage /> <!--密码过期;强制用户更改屏幕锁密码的频率--> < expire-password /> </ uses-policies > </ device-admin > 示例生成apk,该应用具体了设备管理的功能。 本文转自 secondriver 51CTO博客,原文链接:http://blog.51cto.com/aiilive/1718579,如需转载请自行联系原作者

优秀的个人博客,低调大师

那些做Android开发必须知道的ADB命令

以下记录一些比较常用的命令 adb start-server 启动adb服务,如果它没启动的话 adb kill-server 关闭服务 adb devices 查看所连接的设备以及设备所对应的序列号 adb install -r xxxx.apk 安装app,需要注意的是如果连接了两台设备,则会报错,此时可以添加-s <serialNumber>来处理 adb uninstall packagename 卸载app,有时候在手机上卸载App会出现数据清理不干净,导致App再也装不上了,这个时候可以敲命令来卸载 adb shell 进入shell环境 adb shell pm clear packagename 清除应用的数据,很常用吧? adb shell am start -n packagename/packagename.activityname 启动某个应用的某个Activity(以前调试老年机,那种Launcher上没有APP的机器,全靠它啊!!!!!!!) adb connect <device-ip-address> 连接到指定的ip,这个通常配合wifidebug adb shell dumpsys activity top 查看栈顶Activity,可以用来获取包名,可以用来查看其它app的包名 adb shell ps 查看进程信息 adb shell pm list packages -f 查看所有已安装的应用的包名 adb shell dumpsys activity dumpsys系列命令可以帮助我们查看各种信息 am的状态 Activity Manager State adb shell dumpsys package 包信息 Package Information adb shell dumpsys meminfo 内存使用情况Memory Usage adb pull <remote> <local> 从手机复制文件出来,比如把Crash日志写在SD卡上,再pull到电脑上 或者 pull ANR的trace日志 adb push <local> <remote> 向手机发送文件,比如测试热修复补丁~ eg.adb push foo.txt /sdcard/foo.txt adb shell cat /proc/cpuinfo 查看手机CPU,可以看到手机架构(eg.ARMv7) 和几核处理器 可以帮助我们选择so库,排查手机cpu架构相关的问题 不太常用的命令 adb shell df 获取手机磁盘空间 adb shell getprop ro.build.version.release 获取手机系统版本 adb shell dumpsys procstats Memory Use Over Time adb shell dumpsys gfxinfo Graphics State adb version 查看adb版本 adb help 进入adb帮助界面 本文转自 小强测试帮 51CTO博客,原文链接:http://blog.51cto.com/xqtesting/1825339,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android开发过程中的视图组详解

Android在屏幕中控件的组织上,可以将各个视图(控件)组成一个视图组(ViewGroup),视图组是一个包含了其他视图的视图。 ▲图书封面 1.视图组(ViewGroup抽象类) android.view包中ViewGroup类继承了View,因此它本身也具有View的特性。ViewGroup主要的功能在于它可以包含其他控件,作为其他控件的容器。 ViewGroup实现了android.view包中的ViewParent接口,这个类表示一个可以作为其他的View的容器的职责。 ViewGroup也实现了android.view包中的ViewManager接口,因此包含ViewManager中的以下几个方法: public abstract void addView(View view, ViewGroup.LayoutParams params) public abstract void removeView(View view) public abstract void updateViewLayout(View view, ViewGroup.LayoutParams params) addView()以View作为参数,用于将这个View增加为当前视图组的“孩子”;removeView()用于将一个View从视图组中移除;updateViewLayout()用于更新某个View的布局。 ViewGroup.OnHierarchyChangeListener是一个接口,用于监听ViewGroup中的View的层次变化。这个接口中包含了两个监听方法: public abstract void onChildViewAdded (View parent, View child) public abstract void onChildViewRemoved (View parent, View child) 实现一个OnHierarchyChangeListener接口后,这两个方法可以监听包括ViewGroup(包括其继承者)之中的增加和删除孩子的情况。通过ViewGroup的setOnHierarchyChangeListener()方法可以将其设置给一个ViewGroup。 ViewGroup是一个抽象类,其中包含了以下的一个抽象方法: protected abstract void onLayout (boolean changed, int l, int t, int r, int b) ViewGroup中的onLayout()方法将在ViewGroup为它的孩子们分配尺寸和位置的时候被调用,在这个类的实现中,需要调用每一个控件的布局方法为其布局。 提示:onLayout()在View中是一个public的方法,在ViewGroup为protected类型,并且为abstract,由于这个方法在ViewGroup中没有实现,因此ViewGroup本身不可以直接使用。 2.Android的屏幕元素体系 Android UI程序的屏幕体系结构的组织遵循以下原则: 一个屏幕可以包含一个视图; 视图组本身也是一个视图; 视图组可以包含若干个视图。 Android视图和视图组的关系如图3-12所示。 图3-12中左右两图表示的一个屏幕中View组织的结构,左图是各个视图组和控件在一个屏幕之中的示意图;右图为视图组的层次结构图(View Hierarchy),这也是Android中一种常用的表示屏幕中布局的方式。 如图3-12所示,外部最大的框表示整个屏幕,其中包含一个视图组ViewGroup0,ViewGroup0包含三个子视图,即View1、ViewGroup1、ViewGroup2。ViewGroup1本身也是视图组,包含了View2和View3;ViewGroup2本身也是视图组,包含了View4、ViewGroup3和ViewGroup4;ViewGroup4本身也是视图组,包含了View5和View6。 ▲图3-12 视图和视图组的关系(上:屏幕示意图;下:View的层次结构图) 根据以上的原则,当屏幕需要包含多个视图时,必须组织在一个视图组中。由于视图组本身也是一个视图,因此视图组还可以包含视图组。 一个主要的限制是:在没有视图组的情况下,两个以上的视图(也包括视图组)是不能够并列的。例如,在布局文件中,类似下面的写法是不可以的。 <?xml version="1.0" encoding="utf-8"?> <Button android:id="@+id/button"/> <EditText android:id="@+id/edit"/> 3.ViewGroup的继承结构 ViewGroup是所有视图组的基类,它本身是一个不能直接使用的抽象类。在程序中使用的主要是ViewGroup的继承者。 ViewGroup的继承者大部分在android.widget包中,其直接继承者包括:AdapterView、AbsoluteLayout、FrameLayout、LinearLayout、RelativeLayout。这些继承者各自又具有一些继承者。 ViewGroup继承者的体系结构如图3-13所示。 图3-13中所示的ViewGroup继承者都是可以作为容器使用的。这些继承者可以为它们的孩子们提供不同的布局方法,用以确定孩子们相互之间的位置和尺寸关系。 这些继承者又具有一些继承者,有些继承者是不作为容器使用的,仅仅是像一个普通控件一样使用。 ▲图3-13 视图组的继承结构 4.布局参数类 在Android中每个控件在布局文件中能使用的XML属性其实有三类: 其自己的XML属性; 其祖先类的XML属性; 其容器的布局参数。 其中,布局参数是包含这个控件的容器(一个ViewGroup的继承者)所提供的参数。在Android中,每一个ViewGroup的继承者都有一个相对应的名称为{XXX}.LayoutParams的静态子类,表示这个ViewGroup的孩子们中可以使用的布局参数。 这些布局参数类的基类为ViewGroup.LayoutParams,这是一个ViewGroup的静态子类,表示ViewGroup的子对象中可以使用参数。 ViewGroup.LayoutParams包含有两个重要的XML属性:android:layout_width和android:layout_height,它们表示布局对象的宽和高。除了使用实际的尺寸数值外,还有如下两个常用的选项。 “match_parent”或者“fill_parent”:表示能匹配父视图的最大尺寸; “wrap_content”:表示仅包裹孩子的最小尺寸。 ViewGroup.MarginLayoutParams是ViewGroup.LayoutParams的一个继承者,主要用于定义和边缘的空白,它具有android:layout_marginTop,android:layout_marginLeft,android:layout_marginBottom,android:layout_marginRight几个XML属性,表示四个方向的边缘空白。 在ViewGroup的继承者中,都具有一个名称为.LayoutParams的静态子类,这些子类继承关系和ViewGroup子类的继承关系具有相似性。布局参数LayoutParams使用方式如图3-14所示。 ▲图3-14 视图组布局参数的结构 从图3-14中可见,LinearLayout的布局参数LinearLayout.LayoutParams可以被这个布局的孩子们使用,RelativeLayout的布局参数RelativeLayout.LayoutParams可以被这个布局的孩子们使用。但是这里“孩子”的含义,只包括这个容器直接的孩子。例如,图3-14中LinearLayout的孩子有一个是RelativeLayout,RelativeLayout的孩子中能使用的参数就不包括线性布局的参数LinearLayout.LayoutParams。 提示:由于LayoutParams也具有继承关系,因此LinearLayout的孩子们除了可以使用LinearLayout.LayoutParams自己的XML属性,还可以使用其祖先类ViewGroup.LayoutParams的XML属性。 本文转自 wws5201985 51CTO博客,原文链接:http://blog.51cto.com/wws5201985/787672,如需转载请自行联系原作者

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册