android碎片、广播、文件、sqlite存储笔记(二)
1.dp、sp和密度
dp 是密度无关像素的意思,也被称作 dip,和 px 相比,它在不同密度的屏幕中的显示比 例将保持一致。
sp 是可伸缩像素的意思,它采用了和 dp 同样的设计理念,解决了文字大小的适配问题。
Android 中的密度就是屏幕每英 寸所包含的像素数,通常以 dpi 为单位。比如一个手机屏幕的宽是 2
英寸长是3 英寸,如果 它的分辨率是 320*480 像素,那这个屏幕的密度就是 160dpi,如果它的分辨率
是 640*960, 那这个屏幕的密度就是 320dpi,因此密度值越高的屏幕显示的效果就越精细。
在 160dpi 的屏幕上,1dp 等于 1px,而在 320dpi 的屏幕上,1dp 就等于 2px。因此,使用 dp 来
指定控件的宽和高,就可以保证控件在不同密度的屏幕中的 显示比例保持一致。
尽量将控件或布局的大小指定成 match_parent 或 wrap_content,如果必须要指定一个固定值,则使
用 dp 来作为单位,指定文字大小的时候 使用 sp 作为单位。
2.fragment动态替换
动态添加碎片主要分为 5 步。
1. 创建待添加的碎片实例。
2. 获取到 FragmentManager,在活动中可以直接调用 getFragmentManager()方法得到。
3. 开启一个事务,通过调用 beginTransaction()方法开启。
4. 向容器内加入碎片,一般使用 replace()方法实现,需要传入容器 的 id 和待添加的碎片实例。
5. 提交事务,调用 commit()方法来完成。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
tools:context="com.example.fragmenttest.MainActivity">
<fragment
android:id="@+id/left_fragment"
android:name="com.example.fragmenttest.LeftFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
/>
<FrameLayout
android:id="@+id/right_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
<fragment
android:id="@+id/righ_fragment"
android:name="com.example.fragmenttest.RightFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</FrameLayout>
</LinearLayout>
AnotherRightFragment fragment = new AnotherRightFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
fragmentTransaction.replace(R.id.right_layout, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
3.fragment 和 activity 通信
1.activity 获取 fragment
RightFragment rightFragment = (RightFragment) getFragmentManager()
.findFragmentById(R.id.right_fragment);
2.fragment获取所在activity
MainActivity activity = (MainActivity) getActivity();
4.简化启动另一个activity的方法
在NewsContentActivity加入actionStart方法
public class NewsContentActivity extends AppCompatActivity {
public static void actionStart(Context context,
String newsTitle,
String newsContent) {
Intent intent = new Intent(context, NewsContentActivity.class);
intent.putExtra("news_title", newsTitle);
intent.putExtra("news_content", newsContent);
context.startActivity(intent);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.news_content);
String newsTitle = getIntent().getStringExtra("news_title");
// 获取传入的新闻标题
String newsContent = getIntent().getStringExtra("news_content");
// 获取传入的新闻内容
NewsContentFragment newsContentFragment = (NewsContentFragment)
getSupportFragmentManager()
.findFragmentById(R.id.news_content_fragment);
newsContentFragment.refresh(newsTitle, newsContent);
// 刷新NewsContentFragment界面
}
}
按下面调用即可启动
NewsContentActivity.actionStart
(getActivity(),
news.getTitle(),
news.getContent());
5.监听网络变化的广播
public class MainActivity extends AppCompatActivity {
private IntentFilter intentFilter;
private NetworkChangeReceiver networkChangeReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
networkChangeReceiver = new NetworkChangeReceiver();
registerReceiver(networkChangeReceiver, intentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(networkChangeReceiver);
}
class NetworkChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager connectivityManager = (ConnectivityManager)
context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager
.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isAvailable()) {
Toast.makeText(context, "network available", Toast.LENGTH_SHORT)
.show();
} else {
Toast.makeText(context, "network unavailable", Toast
.LENGTH_SHORT)
.show();
}
}
} }
6.发送标准广播
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "received in MyBroadcastReceiver",
Toast.LENGTH_SHORT).show();
}
}
Intent intent = new Intent("com.example.broadcasttest" +
".MY_BROADCAST");
sendBroadcast(intent);
7.读写文件
public class MainActivity extends AppCompatActivity {
private EditText editText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = (EditText) findViewById(R.id.edit);
String inputText = load();
if (!TextUtils.isEmpty(inputText)) {
editText.setText(inputText);
editText.setSelection(inputText.length());
Toast.makeText(this, "load success", Toast.LENGTH_SHORT).show();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d("data", "onDestroy");
String text = editText.getText().toString();
save(text);
}
private void save(String inputText) {
Log.d("data", inputText);
FileOutputStream out = null;
BufferedWriter writer = null;
try {
/*所有的文件都是默认存储到/data/data/<package name>/files/目录下的
MODE_PRIVATE 是默认的操作模式,表示当指 定同样文件名的时候,所写入的内容
将会覆盖原文件中的内容,而 MODE_APPEND 则表示 如果该文件已存在就往文件里
面追加内容,不存在就创建新文件
*/
out = openFileOutput("data", Context.MODE_PRIVATE);
writer = new BufferedWriter(new OutputStreamWriter(out));
writer.write(inputText);
} catch (Exception e) {
Log.d("data", e.toString());
e.printStackTrace();
} finally {
try {
if (writer != null) {
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
private String load() {
FileInputStream in = null;
BufferedReader reader = null;
StringBuilder content = new StringBuilder();
try {
//系统会自动到/data/data/<package name>/files/目录下去加载这个文件
in = openFileInput("data");
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = reader.readLine()) != null) {
content.append(line);
}
} catch (Exception e) {
Log.d("data", e.toString());
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Log.d("data", content.toString());
return content.toString();
}
}
8.SharedPreferences 读写数据
SharedPreferences 文件都是存放在/data/data/<package name>/shared_prefs/目录下的。
第二个参数用于指定操作模式,主要有两种模式可以选 择,MODE_PRIVATE 和 MODE_MULTI_PROCESS。
MODE_PRIVATE 仍然是默认的操 作模式,和直接传入 0 效果是相同的,表示只有当前的应用程序才可以
对这个 SharedPreferences 文件进行读写。MODE_MULTI_PROCESS 则一般是用于会有多个进程中
对同一个 SharedPreferences 文件进行读写的情况
write
SharedPreferences.Editor editor = getSharedPreferences
("data", MODE_PRIVATE).edit();
editor.putString("name", "Tom");
editor.putInt("age", 28);
editor.putBoolean("married", false);
editor.commit(); >read
SharedPreferences pref = getSharedPreferences("data",
MODE_PRIVATE);
String name = pref.getString("name", "");
int age = pref.getInt("age", 0);
boolean married = pref.getBoolean("married", false);
Log.d("MainActivity", "name is " + name);
Log.d("MainActivity", "age is " + age);
Log.d("MainActivity", "married is " + married);
9.SQLite 数据库存储
参考:https://www.oschina.net/question/12_53183 >事务
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.beginTransaction(); // 开启事务
try {
db.delete("Book", null, null);
if (true) {
// 在这里手动抛出一个异常,让事务失败
//throw new NullPointerException();
}
ContentValues values = new ContentValues();
values.put("name", "Game of Thrones");
values.put("author", "George Martin");
values.put("pages", 720);
values.put("price", 20.85);
db.insert("Book", null, values);
db.setTransactionSuccessful(); // 事务已经执行成功
} catch (Exception e) {
e.printStackTrace();
} finally {
db.endTransaction(); // 结束事务
} }
更新
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("price", 10.99);
db.update("Book", values, "name = ?", new String[]{"The Lost Symbol"});
插入
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
// 开始组装第一条数据
values.put("name", "The Da Vinci Code");
values.put("author", "Dan Brown");
values.put("pages", 454);
values.put("price", 16.96);
db.insert("Book", null, values);
// 插入第一条数据
values.clear();