Fragment+ViewPager+TabLayout&EventBus&Banner&SD&SP
TabLayout
Tablayout繼承自HorizontalScrollView,用作頁面切換指示器,因使用簡便功能強大而廣泛使用在App中
TabLayout 的幾個常用屬性值
app:tabBackground 標籤佈局的背景色
app:tabIndicatorColor 指示器的顏色
app:tabIndicatorHeight 指示器的高度(如果不需要指示器可以設置爲0dp)
app:tabMode 顯示模式:默認 fixed(固定),scrollable(可橫向滾動)
app:tabPadding 標籤內邊距
app:tabSelectedTextColor 標籤選中的文本顏色
app:tabTextAppearance 標籤文本樣式
app:tabTextColor 標籤未選中的文本顏色
Fragment+ViewPager+TabLayout結合使用:
xml文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.design.widget.TabLayout
android:id="@+id/tab_id"
app:tabSelectedTextColor="#E5AF35"
app:tabTextColor="#969696"
app:tabIndicatorColor="#E5AF35"
app:tabIndicatorHeight="5dp"
app:tabMode="scrollable"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp">
</android.support.design.widget.TabLayout>
<android.support.v4.view.ViewPager
android:id="@+id/vp_id"
android:layout_weight="8"
android:layout_width="match_parent"
android:layout_height="0dp">
</android.support.v4.view.ViewPager>
</LinearLayout>
MainActivity.java
package com.example.day007;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Window;
import com.example.day007.adapter.MyFragmentAdapter;
import com.example.day007.fragment.OneFragment;
import com.example.day007.fragment.TwoFragment;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private TabLayout tabId;
private ViewPager vpId;
private List<Fragment> list = new ArrayList<>();
private List<String> titles = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
tabId = findViewById(R.id.tab_id);
vpId = findViewById(R.id.vp_id);
list.add(new OneFragment());
list.add(new TwoFragment());
list.add(new OneFragment());
list.add(new TwoFragment());
titles.add("視頻");
titles.add("新聞");
titles.add("圖片");
titles.add("留言");
MyFragmentAdapter myFragmentAdapter = new MyFragmentAdapter(getSupportFragmentManager(), list, titles);
vpId.setAdapter(myFragmentAdapter);
//把viewPager和tabLayout綁定在一起,註釋掉看看效果.
tabId.setupWithViewPager(vpId);
}
}
MyFragmentAdapter.java
package com.example.day007.adapter;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import java.util.ArrayList;
import java.util.List;
/**
* ${FENG}
* 2019-07-11
*/
public class MyFragmentAdapter extends FragmentStatePagerAdapter {
private List<Fragment> list;
private List<String> titles;
public MyFragmentAdapter(FragmentManager fm, List<Fragment> list, List<String> titles) {
super(fm);
this.list = list;
this.titles = titles;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Fragment getItem(int i) {
return list.get(i);
}
//返回與viewpage關聯以後的tablayot的內容
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return titles.get(position);
}
}
EventBus
三個角色
Event:事件,它可以是任意類型,EventBus會根據事件類型進行全局的通知。
Subscriber:事件訂閱者,在EventBus 3.0之前我們必須定義以onEvent開頭的那幾個方法,分別是onEvent、onEventMainThread、onEventBackgroundThread和onEventAsync,而在3.0之後事件處理的方法名可以隨意取,不過需要加上註解@subscribe,並且指定線程模型,默認是POSTING。
Publisher:事件的發佈者,可以在任意線程裏發佈事件。一般情況下,使用EventBus.getDefault()就可以得到一個EventBus對象,然後再調用post(Object)方法即可。
四種線程模型
EventBus3.0有四種線程模型,分別是:
POSTING:默認,表示事件處理函數的線程跟發佈事件的線程在同一個線程。
MAIN:表示事件處理函數的線程在主線程(UI)線程,因此在這裏不能進行耗時操作。
BACKGROUND:表示事件處理函數的線程在後臺線程,因此不能進行UI操作。如果發佈事件的線程是主線程(UI線程),那麼事件處理函數將會開啓一個後臺線程,如果果發佈事件的線程是在後臺線程,那麼事件處理函數就使用該線程。
ASYNC:表示無論事件發佈的線程是哪一個,事件處理函數始終會新建一個子線程運行,同樣不能進行UI操作。
使用
依賴導包(Androidx)
implementation ‘org.greenrobot:eventbus:3.0.0’
用fragment接收eventbus代碼
fragment
public class BlankFragment extends Fragment {
private TextView show;
public BlankFragment() {
// Required empty public constructor
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EventBus.getDefault().register(this);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
// Inflate the layout for this fragment
View inflate = inflater.inflate(R.layout.fragment_blank, container, false);
show = inflate.findViewById(R.id.show);
return inflate;
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void getmsg(Message msg) {
String msg1 = msg.getMsg();
show.setText(msg1);
}
@Override
public void onDestroy() {
super.onDestroy();
EventBus.getDefault().removeAllStickyEvents();
}
}
MainActivity
public class EvevtBus extends AppCompatActivity {
private EditText edit;
private Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_evevt_bus);
edit = (EditText) findViewById(R.id.edit);
btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String msg = edit.getText().toString();
Message message = new Message(msg);
EventBus.getDefault().post(message);
}
});
}
}
Banner
使用
依賴&權限
導入依賴
compile ‘com.youth.banner:banner:1.4.10’
清單文件權限
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Bunner">
<com.youth.banner.Banner
android:id="@+id/banner"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.youth.banner.Banner>
</LinearLayout>
外部類圖片下載器
public class imgLoader extends ImageLoader {
@Override
public void displayImage(Context context, Object path, ImageView imageView) {
Glide.with(context).load(path).into(imageView);
}
}
MainActivity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bunner);
banner = (Banner) findViewById(R.id.banner);
//綁定下載器
banner.setImageLoader(new imgLoader());
//創建圖片集合作爲數據源
ArrayList<String> list = new ArrayList<>();
list.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1571309316416&di=b25fb8a2fee660ae963a41c56c067cc6&imgtype=0&src=http%3A%2F%2Fi0.hdslb.com%2Fbfs%2Farticle%2F49c607dbba21551282e97ac4c71294373b4a488e.jpg");
list.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1571309316412&di=f8e4ac3d1788a1419a961d169eac8504&imgtype=0&src=http%3A%2F%2Fi0.hdslb.com%2Fbfs%2Farticle%2Fc4f07739f34bc111ee50c84b2780a49d850b9cd5.jpg");
list.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1571309316410&di=71bed840c95a5bd8a9dc4899526981bb&imgtype=0&src=http%3A%2F%2Fi0.hdslb.com%2Fbfs%2Farchive%2Fc65f0fb7343516425d1b0750094c111175a4cfb4.jpg");
list.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1571309316406&di=ed83b7a2eb9c9d5ab90ed112d4912bd4&imgtype=0&src=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2F0%2F58a3c9d34cf61.jpg");
banner.setImages(list);
//設置banner樣式
banner.setBannerStyle(BannerConfig.CIRCLE_INDICATOR);
//設置動畫效果
banner.setBannerAnimation(Transformer.DepthPage);
//設置輪播間隔時間
banner.setDelayTime(1000);
//啓動banner
banner.start();
}
}
SP
SharedPreferences
SharedPreferences簡稱Sp(後面都會稱Sp),是一種輕量級的數據存儲方式,採用Key/value的方式 進行映射,最終會在手機的/data/data/package_name/shared_prefs/目錄下以xml的格式存在。
Sp通常用於記錄一些參數配置、行爲標記等!因爲其使用簡單,所以大多數開發者用起來很爽!
但是 請注意:千萬不要使用Sp去存儲量大的數據,也千萬不要去讓你的Sp文件超級大,否則會大大影響應用性能, 甚至出現ANR(程序無響應)
特點:
保存少量的數據,且這些數據的格式非常簡單。 存儲5種原始數據類型: boolean, float, int, long, String
比如應用程序的各種配置信息(如是否打開音效、是否使用震動效果、小遊戲的玩家積分等),記住密碼功能,音樂播放器播放模式。
技能要點: (1)如何存儲數據 (2)如何獲取數據
使用方式
**步驟1:**得到SharedPreferences對象 getSharedPreferences(“文件的名稱”,“文件的類型”);
(1).Context.MODE_PRIVATE:指定該SharedPreferences數據只能被應用程序讀寫
(2)MODE_APPEND:檢查文件是否存在,存在就往文件追加內容,否則就創建新文件。
以下不在建議使用
(3).Context.MODE_WORLD_READABLE:指定該SharedPreferences數據能被其他
應用程序讀,但不能寫。
(4).Context,MODE_WORLD_WRITEABLE:指定該SharedPreferences數據能被其他應用程序寫,但不能讀。
**步驟2:**得到 SharedPreferences.Editor編輯對象
SharedPreferences.Editor editor=sp.edit();
**步驟3:**添加數據
editor.putBoolean(key,value)
editor.putString()
editor.putInt()
editor.putFloat()
editor.putLong()
**步驟4:**提交數據 editor.commit()或者apply()(推薦用這個.異步提交)
Editor其他方法: editor.clear() 清除數據 editor.remove(key) 移除指定key對應的數據
SD
四個方法展示SD卡儲存
public class FileUtils {
//方法1:向SD卡中寫json串
public static void write_json(String json) {
//判斷是否掛載
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
//獲取SD卡根路徑:mnt/shell/emulated/0
File file=Environment.getExternalStorageDirectory();
FileOutputStream out=null;
try {
//創建輸出流
out= new FileOutputStream(new File(file,"json.txt"));
out.write(json.getBytes());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(out!=null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
//方法2:從SD卡中讀取json串
public static String read_json() {
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
File file = Environment.getExternalStorageDirectory();
FileInputStream inputStream = null;
StringBuffer sb=new StringBuffer();
try {
inputStream=new FileInputStream(new File(file,"json.txt"));
byte[] b=new byte[1024];
int len=0;
while((len=inputStream.read(b))!=-1){
sb.append(new String(b,0,len));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(inputStream!=null){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString();
}else{
return "";
}
}
//方法3:從SD卡中讀取一張圖片
public static Bitmap read_bitmap(String filename) {//filename圖片名字
Bitmap bitmap=null;
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
File file=Environment.getExternalStorageDirectory();
File file1 = new File(file, filename);
//BitmapFactory可以直接根據SD卡圖片路徑轉成一個bitmap對象
bitmap= BitmapFactory.decodeFile(file1.getAbsolutePath());
}
return bitmap;
}
//方法4:網絡下載一張圖片存儲到SD卡中
public static void write_bitmap(String url) {//網址
new MyTask().execute(url);
}
static class MyTask extends AsyncTask<String,String,String> {
@Override
protected String doInBackground(String... strings) {
FileOutputStream out=null;
InputStream inputStream=null;//網絡連接的輸入流
HttpURLConnection connection=null;//向SD卡寫的輸出流
try {
URL url= new URL(strings[0]);
connection= (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(5*1000);
connection.setReadTimeout(5*1000);
if (connection.getResponseCode()==200){
inputStream = connection.getInputStream();
//TODO 獲取SD卡的路徑
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {//是否掛載
File file = Environment.getExternalStorageDirectory();
out = new FileOutputStream(new File(file,"xiaoyueyue.jpg"));
byte[] bytes=new byte[1024];
int len=0;
while((len=inputStream.read(bytes))!=-1){
out.write(bytes,0,len);
}
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
//關流
if(out!=null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(inputStream!=null){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(connection!=null){
connection.disconnect();
}
}
return null;
}
}
}