Android 开发知识点总结

550 阅读13分钟

很可能下一份工作就不是从事 Android 了,现在的确不在做了[微笑],在做 Android 开发的这段时期里还是总结了很多的基础知识的,所以后续还是会有几篇会一一上传。惭愧,本人目前还是菜B一枚,还没有达到研究源码发表一些牛掰尔尔,无论是博客还是其它的笔记都是一些基础的内容知识点,我总是相信再高深的知识如果基础不牢也没法去拥有掌握,如下罗列都是自己在开发中遇到的一些琐屑知识点,是写给自己看的,当然很多都可以从网上查到,我只不过做了个归纳、整理,方便查阅。如果看客觉得有用,不用客气,觉得没用,也不要咒骂,抱怨!

直接复制项目需要注意:

  • 要改动的地方
    • 项目名字
    • 应用包名
    • 重新导入R文件

广播(BroadcastReceiver)

  • 是继承自 BroadcastReceiver 的, 并重写了父类的 onReceive()方法

  • 动态注册的广播接收器一定都要取消注册才行

  • 发送有序广播 sendOrderedBroadcast(intent, null);

  • 既然已经获得了接收广播的优先权,那么 MyBroadcastReceiver 就可以选择是否允许广 播继续传递了 abortBroadcast();

  • 为了能够简单地解决广播的安全性问题,Android引入了一套本地广播机制,使用这个 机制发出的广播只能够在应用程序的内部进行传递, 并且广播接收器也只能接收来自本应用 程序发出的广播,这样所有的安全性问题就都不存在了

      @Override
      protected void onCreate(Bundle savedInstanceState) {
      	super.onCreate(savedInstanceState);
      	setContentView(R.layout.activity_main);
      	localBroadcastManager = LocalBroadcastManager.getInstance(this);
      	
      	Button button = (Button) findViewById(R.id.button);
      	button.setOnClickListener(new OnClickListener() {
      		@Override
      		public void onClick(View v) {
      			Intent intent = new Intent("com.excel.localbroadcast.LOCAL_BROADCAST");
      			localBroadcastManager.sendBroadcast(intent);
      		}
      	});
      	intentFilter = new IntentFilter();
      	intentFilter.addAction("com.excel.localbroadcast.LOCAL_BROADCAST");
      	localReceiver = new LocalReceiver();
      	localBroadcastManager.registerReceiver(localReceiver, intentFilter);
      }
    

另外还有一点需要说明,本地广播是无法通过静态注册的方式来接收的,其实这也完全可以理解,因为静态注册主要就是为了让程序在未启动的情况下也能收到广播,而发送本地广播时,我们的程序肯定是已经启动了,因此也完全不需要使用静态注册的功能。使用本地广播的几点优势。

  1. 可以明确地知道正在发送的广播不会离开我们的程序, 因此不需要担心机密数据泄 漏的问题。
  1. 其他的程序无法将广播发送到我们程序的内部, 因此不需要担心会有安全漏洞的隐 患。
  2. 发送本地广播比起发送系统全局广播将会更加高效。

Android中主要提供了三种方法用于得到 SharedPreferences对象

  • Context 类中的 getSharedPreferences() 方法

      SharedPreferences sp = context.getSharedPreferences("ip", Context.MODE_PRIVATE);
    
  • Activity类中的 getPreferences() 方法

      SharedPreferences sp = getSharedPreferences("ip", MODE_PRIVATE);
    
  • PreferenceManager 类中的 getDefaultSharedPreferences() 方法

      button.setOnClickListener(new OnClickListener() {
      	@Override
      	public void onClick(View v) {
      		SharedPreferences.Editor editor = getSharedPreferences("data",MODE_PRIVATE).edit();
      		editor.putString("name", "Tom");
      		editor.putInt("age", 28);
      		editor.putBoolean("married", false);
      		editor.commit();
      	}
      });
    

SQLite创建表

create table Book (
id integer primary key autoincrement,
author text,
price real,
pages integer,
name text)

integer 表示整型,real表示浮点型,text 表示文本类型,blob 表示二进制类型

使用cmd命令查看表

  • 在环境变量里配置plant-tools路径
  • 打开cmd,输入adb shell,进入手机存储目录
  • cd /data/data/com.lhg.sqlitedatabase/databases路径下
  • sqlite3 数据库名.db -->查看数据库
  • .table -->查看数据库中所有表
  • pragma table_info(表名) -->查看表的数据结构

输入.mode line命令切换显示模式,然后重新运行pragma命令

  • .schema -->查看建表语句
  • .exit -->退出

使用SQL基本语句操作数据库

	public void insert() {
		// 如果数据库不存在,先创建数据库,再获取可读可写的数据库对象,如果数据库存在,就直接打开
		db.execSQL("insert into person(name, salary,phone)values(?,?,?)", new Object[] { "张三", "5000", 1384700 });
		db.execSQL("insert into person(name, salary,phone)values(?,?,?)", new Object[] { "李四", 200, 1872093 });
		db.execSQL("insert into person(name, salary,phone)values(?,?,?)", new Object[] { "王五", 10000, 1322093 });
		db.execSQL("insert into person(name, salary,phone)values(?,?,?)", new Object[] { "李毅", 100, 1312093 });
	}

	public void delete() {
		db.execSQL("delete from person where name=?", new Object[] { "张三" });
	}

	public void update() {
		db.execSQL("update person set salary=? where name=?", new Object[] { 20000, "王五" });
	}

	public void select() {
		Cursor cursor = db.rawQuery("select * from person", null);
		while (cursor.moveToNext()) {
			String name = cursor.getString(cursor.getColumnIndex("name"));
			String salary = cursor.getString(cursor.getColumnIndex("salary"));
			String phone = cursor.getString(cursor.getColumnIndex("phone"));
			System.out.println(name + "--->" + salary + "-->" + phone);
		}
	}

使用android提供的api操作数据库

	// 使用Api插入数据库
	public void insertApi() {
		ContentValues values = new ContentValues();
		// 第一个属性必须和数据库中字段对应
		values.put("name", "刘文勇");
		values.put("salary", 2500);
		values.put("phone", 110);
		db.insert("person", null, values);
	}

	// 使用api删改数据库
	public void deleteApi() {
		// 如果数据库中有多个name相同的对象,可以用以下方式来指定,
		int i = db.delete("person", "name=? and _id=?", new String[] { "张三", "3" });
		System.out.println(i);
	}

	public void updateApi() {
		ContentValues values = new ContentValues();
		values.put("phone", 119);
		int i = db.update("person", values, "name=?", new String[] { "张三" });
		System.out.println(i);
	}

	public void selectApi() {
		Cursor cursor = db.query("person", null, null, null, null, null, null);
		while (cursor.moveToNext()) {
			String name = cursor.getString(cursor.getColumnIndex("name"));
			String salary = cursor.getString(cursor.getColumnIndex("salary"));
			String phone = cursor.getString(cursor.getColumnIndex("phone"));
			System.out.println(name + "-->" + salary + "-->" + phone);
		}
	}

事务,经典例子,银行转账

public void transaction() {
	try {
		// 开启事务
		db.beginTransaction();
		ContentValues values = new ContentValues();
		values.put("salary", 9000);
		db.update("person", values, "name=?", new String[] { "李四" });

		values.clear();// 建议写上
		values.put("salary", 6000);
		db.update("person", values, "name=?", new String[] { "杨文" });
		// int i = 3/0;//事务不执行
		// 设置 事务执行成功
		db.setTransactionSuccessful();
	} finally {
		// 关闭事务,同时提交,如果已经设置事务执行成功,那么sql语句就生效了,反之,sql语句回滚
		db.endTransaction();
	}
}

装载布局的三种方式

View view = getLayoutInflater().inflate(R.layout.add_black_number, null);
View view =LayoutInflater.from(this).inflate(R.layout.add_black_number, null);
View view = View.inflate(this, R.layout.add_black_number,null);

访问assets目录下的文件的路径写法(比如数据库)

//路径
private static final String PATH="data/data/com.excel.mobileSafe/files/address.db"
//拿到数据库对象
SQLiteDatabase database = SQLiteDatabase.openDatabase(PATH,null,SQLiteDatabase.OPEN_READONLY)

ListView适配器通过构造方法关联MainActivity

private List<String> mData;
private LayoutInflater mInflater;
public  ListViewAdapter(Context context,List<String> mData) {
	// TODO Auto-generated constructor stub
	this.mData = mData;
	mInflater = LayoutInflater.from(context);
}

TextView、EditText默认是不可以点击的,设置属性

android:clickable="true"

两个界面切换的动画

overridePendingTransition()

设置图片没有背景

android:background="@null"

把RadioButton左边的小圆圈按钮去掉

android:button="@null"

ListView无选择效果

android:listSelector="@null"

联系人URI

  • ContactsContract.Contacts.CONTENT_URI:管理联系人的URI
  • ContactsContract.CommonDataKinds.Phone.CONTENT_URI:管理联系人电话的URI
  • ContactsContract.CommonDataKinds.Email.CONTENT_URI:管理联系人email的URI
  • String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID))//获取联系人ID
  • String name = cursor.getString(cursor.getColumn(ContactsContract.Contacts.DISPLAY_NAME))//获取联系人姓名

打电话

Intent intent = new Intent();
//设置动作,打电话
intent.setAction(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:" + phone));
//把意图告诉系统
startActivity(intent);
//设置权限
<uses-permission android:name= "android.permission.CALL_PHONE"/>

分享文本

Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.setType("text/plain");//image/jpeg
intent.putExtra(Intent.EXTRA_TEXT, "么么哒!");
startActivity(intent);

在当前分享文本activity中配置 <action android:name="android.intent.action.SEND" /><data android:mimeType="text/plain" />

为ViewPager设置监听,用addOn....

viewPager.addOnPageChangeListener(new OnPageChangeListener() {
		@Override
		public void onPageSelected(int position) {
			System.out.println("当前条目"+position);
		}
		
		@Override
		public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
			// TODO Auto-generated method stub		
		}
		
		@Override
		public void onPageScrollStateChanged(int state) {
			// TODO Auto-generated method stub
		}
	});

状态选择器(比如ViewPager 时屏幕下方的小圆点的状态) selector_dots

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <!-- 如果状态可用(在当前页),则为白色 -->
	<item android:state_enabled="true"  android:drawable="@drawable/dot_focus"/>
	<item android:drawable="@drawable/dot_unfocus"/>
</selector>

dot_focus.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" >
	<solid android:color="#ffffff"/>
</shape>	

dot_unfocus.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" >
	<solid android:color="#aa000000"/>
</shape>

在代码中绘制小圆点

private void initDots() {
	for (int i = 0; i < mContent.size(); i++) {
		View view = new View(this);// 用于显示小圆点
		LayoutParams params = new LayoutParams(10, 10);// 小圆点的大小
		view.setLayoutParams(params);
		if (i != 0) {
			params.leftMargin = 7;// 设置每个圆点的间隔
		}
		view.setBackgroundResource(R.drawable.selector_dot);
		dots.addView(view);// 把小圆点添加到先行布局里去
	}
}

更新小圆点位置

private void updateDots() {
	int currentItem = viewPager.getCurrentItem() % mContent.size();
	for (int i = 0; i < dots.getChildCount(); i++) {
		dots.getChildAt(i).setEnabled(i == currentItem);
	}
}

Android如何设置定时每十分钟执行一次任务

private Handler handler  = new Handler(){
	public void handleMessage(Message msg) {
		super.handleMessage(msg);
		if(msg.waht == 1){
			//todo something....
		}
	}
};
new Timer(true).schedule(new TimerTask() {
		@Override
		public void run() {
			Message msg = Message.obtain();
		  	msg.what = 1;
		  	handler.sendMessage(msg);
		}
	}, 200, 1000);

ListView在代码中动态设置背景、滚动条

listView.setBackgroundResource(R.drawable.btn_default_transparent_normal);//设置背景
listView.setVerticalScrollBarEnabled(false);//设置滚动条是否可见
android:scrollbars="none" //ListView在XML中设置滚动条不可见

editText限制输入内容的4种方法

<!-- 方法1 xml中配置inputType。 -->
<EditText
    android:id="@+id/et1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="只限数字(xml中 配置inputType)"
    android:inputType="number" />

<!-- 方法2 xml中配置digits -->
<EditText
    android:id="@+id/et2"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:digits=" .@~-,:*?!#/\\=+?^;%$()[]{}|`<>&"'_0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLIMNOPQRSTUVWXYZ"
    android:hint="只限自定义特殊字符(xml中  配置digits)" />

//方式3:java中使用setKeyListener,添加DigitsKeyListener。
//private final static String ET3_DIGITS = "abcd";
//et3.setKeyListener(DigitsKeyListener.getInstance(ET3_DIGITS));
<EditText
    android:id="@+id/et3"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="只限abcd(java中使用addTextChangedListener)" />

//方法4:java中使用setFilters,添加InputFilter。
<EditText
    android:id="@+id/et4"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="只限wxyz(java中使用setFilters)" />
	
private final static String ET4_DIGITS = "wxyz";
et4.setFilters(new InputFilter[] {new InputFilter() {
	/**source:你即将输入的字符序列
	 * start:默认为0,  end:你即将输入的字符序列的长度
	 * dest:当前EditText显示的内容
	 * 经测试dstart和dend 总是相等,都表示输入前光标所在位置
	 */
	@Override
	public CharSequence filter(CharSequence source, int start, int end,
			Spanned dest, int dstart, int dend) {			

        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < source.length(); i++) {
            if (ET4_DIGITS.indexOf(source.charAt(i)) >= 0) {
                sb.append(source.charAt(i));
            }
        }
        return sb;
	}
}});

使用代码锁定横竖屏

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)

横竖屏切换时不调用各个生命周期

android:configChanges="orientation|keyboardHidden|ScreenSize"

或是在AndroidManifest.xml中配置

android:screenOrientation="landscape"是限制此页面横屏显示,
android:screenOrientation="portrait"是限制此页面数竖屏显示。 

Activity的View界面全屏

<!--隐藏标题栏-->
requestWindowFeature(Window.FEATURE_NO_TITLE); 
<!--隐藏信号栏--> 
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);  

用程序生成的秘钥得到API

用程序生成的秘钥得到API

全局去掉标题栏

 <style name="AppTheme" parent="AppBaseTheme">
    <item name="android:windowNoTitle">true</item>
 </style>

EditText属性操作

et.requestFocus(); //请求获取焦点
et.clearFocus(); //清除焦点
et.setSelectAllOnFocus(true);//获得焦点时全选文本
et.setCursorVisible(false);//设置光标不显示
et.setSelection(int index);//设置光标到指定位置,当内容过多时,可通过该设置让内容显示在屏幕上

EditText设置焦点监听

editText.setOnFocusChangeListener(new OnFocusChangeListener() {
		@Override
		public void onFocusChange(View v, boolean hasFocus) {
			if (hasFocus) {
				//得到焦点
			}else {
				//失去焦点
			}
		}
	});

EditText对文本的监听

editText.addTextChangedListener(new TextWatcher() {
		@Override
		public void onTextChanged(CharSequence s, int start, int before, int count) {
		}

		@Override
		public void beforeTextChanged(CharSequence s, int start, int count, int after) {
		}

		@Override
		public void afterTextChanged(Editable s) {
			
		}
	});

对android软键盘的操作

在XML布局中设置不同android:imeOptions时软键盘回车键显示的不同效果

1.android:imeOptions=”actionDone”	软键盘右下角显示”完成
2.android:imeOptions=”actionGo”		软键盘右下角显示”前往
3.android:imeOptions=”actionNext”	软键盘右下角显示”下一项
4.android:imeOptions=”actionPrevious”	软键盘右下角显示"上一项"
5.android:imeOptions=”actionSearch”		软键盘右下角显示"搜索"
6.android:imeOptions="actionSend"		软键盘右下角显示"发送"

要给EditText设置inputType或singleLine属性

对软键盘设置监听

editText.setOnEditorActionListener(new OnEditorActionListener() {
		@Override
		public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
			//获得一个输入法管理器对象
		    inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
			switch (actionId) {
			case EditorInfo.IME_ACTION_SEARCH:
				//隐藏软键盘
				inputMethodManager.hideSoftInputFromWindow(v.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
				//执行其它操作
				break;
			case EditorInfo.IME_ACTION_NEXT:
				//隐藏软键盘
				inputMethodManager.hideSoftInputFromWindow(v.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
				//执行其它操作
				break;
			........
			
			default:
				break;
			}
			return true;
		}
	});

SimpleAdapter 用法

public class MainActivity extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		ListView listView = (ListView) findViewById(R.id.listView1);
		//第四个参数内容要和Map的键名一致
		SimpleAdapter adapter = new SimpleAdapter(this, getData(), R.layout.listview_item, new String[]{"photo","name"}, new int[]{R.id.iv_photo,R.id.tv_name});
		listView.setAdapter(adapter);
	}

	private List<Map<String, Object>> getData() {
		List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();

		Map<String, Object> map1 = new HashMap<String, Object>();
		map1.put("photo", R.drawable.img1);
		map1.put("name", "林洪川");
		data.add(map1);

		Map<String, Object> map2 = new HashMap<String, Object>();
		map2.put("photo", R.drawable.img2);
		map2.put("name", "刘和广");
		data.add(map2);
		.........
		
		return data;
	}
}

点击Button弹出对话框

public void btnClick(View view){
	AlertDialog.Builder builder = new Builder(this);
	builder.setIcon(...);
	builder.setTitle(...);
	buildr.setMessage(...);
	builder.setPositiveButton..
	builder.setNegativeButton..
	AlertDialog dialog = builder.create();//使用创建器,生成一个对话框对象
	dialog.show();
	//如下两句可以修改确定取消按钮的颜色,必须写dialog.show()后面
	dialog.getButton(dialog.BUTTON_NEGATIVE).setTextColor(Color.RED);
    dialog.getButton(dialog.BUTTON_POSITIVE).setTextColor(Color.BLUE);
}

从系统图库中选择图片并压缩大小显示在ImageView中

// 得到图片的内容uri
Uri uri = data.getData();
// 图库中图片的数据参数
String[] picPathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(uri, picPathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(picPathColumn[0]);
picturePath = cursor.getString(columnIndex);
// 把图片路径显示到TextView中
tvPhotoPath.setText(picturePath);
ivPhoto.setImageBitmap(compressImg());

public Bitmap compressImg(){
	BitmapFactory.Options options = new BitmapFactory.Options();
	options.inJustDecodeBounds = true;//只加载图片大小
	BitmapFactory.decodeFile(picturePath, options);
	//缩放图片  18行
	double ratio = Math.max(options.outWidth*1.0d/1024f,options.outHeight*1.0d/1024f);
	options.inSampleSize = (int) Math.ceil(ratio);
	options.inJustDecodeBounds = false;//加载图片
	Bitmap bitmap = BitmapFactory.decodeFile(picturePath,options);
	return bitmap;
}
//计算缩放比例(可替换18行)
Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics displayMetrics = new DisplayMetrics();
display.getMetrics(displayMetrics);
//屏幕宽高
int screenWidth = displayMetrics.widthPixels;
int screenHeight = displayMetrics.heightPixels;
//图片宽高
int imageWidth = options.outWidth;
int imageHeight = options.outHeight;
int widthScale = imageWidth/screenWidth;
int heightScale = imageHeight/screenHeight;
int scale = widthScale > heightScale? widthScale:heightScale;

drawable 转 bitmap

public static Bitmap drawable2bitmap(Drawable drawable) {
    //如果本身就是一个包装了bitmap的drawable对象,直接从现有的Drawable中取出Bitmap:
    if (drawable instanceof BitmapDrawable) {
        return ((BitmapDrawable) drawable).getBitmap();
    }
    Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
    //注意,下面三行代码要用到,否在在View或者surfaceview里的canvas.drawBitmap会看不到图
    Canvas canvas = new Canvas(bitmap);
    drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
    drawable.draw(canvas);
    return bitmap;
}

bitmap 转 drawable

public static Drawable bitmap2drawable(Context context, Bitmap bitmap){
    return new BitmapDrawable(context.getResources(),bitmap);
}

给 LinearLayout 加分割线(一起使用才有效果)

android:divider="@drawable/divider"
android:showDividers="middle"

Notification 基本使用(普通服务)

//点击通知进入通知详情页
Intent intent = new Intent(this,NotificationActivity.class);
PendingIntent pi = PendingIntent.getActivity(this,0,intent,0);
//使用support-v4包中NotificationCompat类在所有Android系统正常工作
Notification notification = new NotificationCompat.Builder(this)
        .setContentTitle("2016年12月24日星期五")
        .setContentText("今天天气阴天,会下雨,么么哒")
        .setWhen(System.currentTimeMillis())
        .setSmallIcon(R.mipmap.ic_launcher)
		.setContentIntent(pi)
		.setAutoCancel(true)//进入详情页后把状态栏的通知图标取消
        .build();
//获取通知服务
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(1, notification);
//manager.cancel(1);//这里取消也可以

Notification基本使用(前台服务)

PendingIntent pi = PendingIntent.getActivity(this,0,intent,0);
Notification notification = new NotificationCompat.Builder(this)
        .setContentTitle("this is content title")
        .setContentText("this is content text")
        .setWhen(System.currentTimeMillis())
        .setSmallIcon(R.mipmap.ic_launcher)
        .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
        .setContentIntent(pi)
        .build();
startForeground(1,notification);//这个方法会让MyService变成一个前台服务

前台服务和普通服务的最大区别就在于它会一直有一个正在运行的图标在系统的状态栏显示(普通服务会在点击通知进入详情页后消失)

判断Wifi是否开启

WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
boolean enabled = wm.isWifiEnabled();

获取系统最大音量

AudioManager am = (AudioManager) getSystemService(AUDIO_SERVICE);
int max = am.getStreamMaxVolume(AudioManager.STREAM_SYSTEM);

获取当前音量

AudioManager am = (AudioManager) getSystemService(AUDIO_SERVICE);
int current = am.getStreamMaxVolume(AudioManager.STREAM_RING);

判断网络是否有连接

ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo();
boolean isAvailable = info.isAvailable();

TabLayout使用(ViewPager+Fragment+FragmentPagerAdapter)

  • 创建Fragment

      public static final String ARGS_PAGE = "args_page";
      private int mPage;
      public static PageFragment newInstance(int page) {
          Bundle args = new Bundle();
          args.putInt(ARGS_PAGE, page);
          PageFragment fragment = new PageFragment();
          fragment.setArguments(args);
          return fragment;
      }
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          mPage = getArguments().getInt(ARGS_PAGE);
      }
      @Nullable
      @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
          View view = inflater.inflate(R.layout.fragment_page,container,false);
          TextView textView = (TextView) view.findViewById(R.id.textView);
          textView.setText("第"+mPage+"页");
          return view;
      }
    
  • 适配器类

      class MyFragmentPagerAdapter extends FragmentPagerAdapter {
          public final int COUNT = 5;
          private String[] titles = new String[]{"Tab1", "Tab2", "Tab3", "Tab4", "Tab5"};
          private Context context;
          public MyFragmentPagerAdapter(FragmentManager fm, Context context) {
              super(fm);
              this.context = context;
          }
          @Override
          public Fragment getItem(int position) {
              return PageFragment.newInstance(position + 1);
          }
          @Override
          public int getCount() {
              return COUNT;
          }
          @Override
          public CharSequence getPageTitle(int position) {
      		 //給tab加上图片
              /*Drawable image = mContext.getResources().getDrawable(imageId[position]);
              image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight());
              SpannableString spannableString = new SpannableString("  " + tabTitles[position]);
              ImageSpan imageSpan = new ImageSpan(image, ImageSpan.ALIGN_BASELINE);
              spannableString.setSpan(imageSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
              return spannableString;*/
    
              return titles[position];
          }
      }
    
  • TabLayout的使用

      MyPagerAdapter mAdapter = new MyPagerAdapter(getSupportFragmentManager(),this);
      mViewPager.setAdapter(mAdapter);
      mTabs.setupWithViewPager(mViewPager);
      mTabs.setSelectedTabIndicatorColor(Color.CYAN);//设置指示器颜色
      mTabs.setTabTextColors(Color.BLACK,Color.WHITE);//设置选中颜色
      //tab标签太少,没有占满屏幕宽度,作如下设置
      mTabs.setTabMode(TabLayout.MODE_FIXED);//也可在布局app:tabGravity="fill "app:tabMode="fixed"
      mTabs.setTabGravity(TabLayout.GRAVITY_FILL);
    

生成 JSON 对象和数组

  • 创建一个 map,通过构造方法将 map 转换成 json 对象

       Map<String, Object>map =new HashMap<String, Object>();
       map.put("name", "zhangsan ");
       map.put("age", 24);
       JSONObject json =new JSONObject(map);
    
  • 创建一个 json 对象,通过 put 方法添加数据

        JSONObject json=new JSONObject();
        json.put("name", "zhangsan "); 
        json.put("age", 24);
    
  • 生成 JSON 数组:创建一个 list,通过构造方法将 list 转换成 json 对象

       Map<String, Object>map1 =new HashMap<String, Object>();
       map1.put("name", "zhangsan ");
       map1.put("age", 24);
       Map<String, Object>map2 =new HashMap<String, Object>();
       map2.put("name", "lisi");
       map2.put("age", 25);
       List<Map<String, Object>>list=new ArrayList<Map<String,Object>>();
       list.add(map1);
       list.add(map2);
       JSONArray array=new JSONArray(list);
    

Android6.0权限申请

`if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
    }
.....

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode) {
        case 1:
            if (grantResults.length > 0 && grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "拒绝权限将无法使用程序", Toast.LENGTH_SHORT).show();
                finish();
            }
            break;
        default:
            break;
    }
}`

待续。。。。