Android中級思路

一 二級列表(ExpandableListView)

1.1 死數(shù)據(jù)步驟:

①創(chuàng)建布局找控件
②數(shù)據(jù)源(兩個集合:groupLists, childLists:泛型是<ArrayList<String>>)
③創(chuàng)建適配器:自定義一個類繼承自:BaseExpandableListAdapter并重寫十個方法 注意:如果想要子條目實現(xiàn)點擊事件監(jiān)聽適配器中isChildSelectable方法設(shè)置為true
④設(shè)置適配器

1.2 Elv監(jiān)聽:

        //父條目點擊事件監(jiān)聽
        elv.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
            @Override
            public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
                Toast.makeText(MainActivity.this, grouplist.get(groupPosition), Toast.LENGTH_SHORT).show();
                return false;
            }
        });
        //子條目點擊事件監(jiān)聽 注意:適配器中isChildSelectable方法設(shè)置為true
        elv.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
            @Override
            public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
                Toast.makeText(MainActivity.this, childList.get(groupPosition).get(childPosition), Toast.LENGTH_SHORT).show();
                return false;
            }
        });
        //打開一個新的條目關(guān)閉其他條目
        elv.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
            @Override
            public void onGroupExpand(int groupPosition) {
                int count = elv.getExpandableListAdapter().getGroupCount();
                for (int i = 0; i < count; i++) {
                    if (i < groupPosition) {
                        elv.collapseGroup(i);
                    } else if (i > groupPosition) {
                        elv.collapseGroup(i);
                    }
                }
            }
        });

二 側(cè)滑

2.1 側(cè)滑菜單

①添加依賴

(implementation'com.android.support:design:29.0.2')

②創(chuàng)建布局:

DrawerLayout、Toolbar厨钻、NavigationView(menu、header)

③設(shè)置actionbar:toolbar設(shè)置標(biāo)題、logo、關(guān)聯(lián)toolbar和側(cè)滑

④監(jiān)聽事件:頭部監(jiān)聽、側(cè)滑菜單監(jiān)聽蕾域、DrawerLayout脓杉、Home旋轉(zhuǎn)開關(guān)

⑤沉浸式狀態(tài)欄

//當(dāng)側(cè)滑的時候主界面跟隨 X 軸移動
dl.addDrawerListener(new DrawerLayout.DrawerListener() {
            @Override
            public void onDrawerSlide(@NonNull View drawerView, float slideOffset) {
                cl.setX(drawerView.getRight());
            }
            //此處省略三個方法......
}

2.2 選項菜單

①創(chuàng)建選項菜單(onCreateOptionsMenu)

    public boolean onCreateOptionsMenu(Menu menu) {
        menu.add(0, 0, 0, "線性布局").setIcon(R.mipmap.ic_launcher_round).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
        return super.onCreateOptionsMenu(menu);
    }

②選項菜單的點擊事件(onOptionsItemSelected)

③Fragment中加setHasOptionsMenu(true);

④使選項菜單內(nèi)容以標(biāo)題的樣式顯示在標(biāo)題上:
.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS)

2.3 上下文菜單

①注冊上下文菜單(registerForContextMenu())

②創(chuàng)建上下文菜單(onCreateContextMenu)

③上下文菜單的點擊事件(onContextItemSelected)

Toolbar使用詳情

//側(cè)滑菜單item圖片顯示
nv.setItemIconTintList(null);
//設(shè)置 Logo
 toolbar.setLogo(R.mipmap.logo); 
// 設(shè)置主標(biāo)題  
toolbar.setTitle("Title"); 
// 設(shè)置副標(biāo)題 
 toolbar.setSubtitle("Sub Title"); 
//設(shè)置toolbar糟秘,將Toolbar設(shè)置到界面上  
setSupportActionBar(toolbar); 
//左邊的小箭頭(注意某些版本api需要在setSupportActionBar(toolbar)之后才有效果)  
toolbar.setNavigationIcon(R.mipmap.back); 
//菜單點擊事件(注意需要在setSupportActionBar(toolbar)之后才有效果)
  toolbar.setOnMenuItemClickListener(onMenuItemClick);
//點擊頭部
View headerView = nv.getHeaderView(0);
        View iv = headerView.findViewById(R.id.iv);
        iv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "點擊了頭部", Toast.LENGTH_SHORT).show();
            }
        });
//Home旋轉(zhuǎn)開關(guān)
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, dl, toolbar, R.string.app_name, R.string.app_name);
        dl.addDrawerListener(toggle);
        toggle.syncState();

android:fitsSystemWindows="true"
//在res文件夾下創(chuàng)建values-v21,復(fù)制styles.xml并添加屬性 注意:修改為.NoActionBar
  <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimary</item>
        <item name="colorAccent">@color/colorAccent</item>
        <!--透明狀態(tài)欄-->
        <item name="android:statusBarColor">#00ffffff</item>
    </style>

//選項菜單不遮蔽標(biāo)題欄 
//1.在styles文件里編寫此代碼
    <style name="OverflowMenuStyle" parent="Widget.AppCompat.Light.PopupMenu.Overflow">
        <item name="overlapAnchor">false</item>
    </style>
//2.在toolbar中調(diào)用此方法:
    android:theme="@style/OverflowMenuStyle"

三 RecyclerView

3.1 RecyclerView的使用步驟

①添加依賴(implementation 'com.android.support:recyclerview-v7:29.0.2')
②創(chuàng)建布局(寬、高必須充滿)
③找控件
④設(shè)置布局管理器(線性布局球散,網(wǎng)格布局和瀑布流)
⑤獲取數(shù)據(jù)(切換子線程的方法)
⑥創(chuàng)建適配器——重寫三個方法尿赚,通過接口回調(diào)實現(xiàn)點擊事件
⑦設(shè)置適配器

布局管理器:

//線性布局
rv.setLayoutManager(new LinearLayoutManager(this));
//網(wǎng)格布局
rv.setLayoutManager(new GridLayoutManager(this, 3));
//瀑布流
rv.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
3.2 接口回調(diào):

類A調(diào)用類B的方法b(),類B在回調(diào)類A的方法a(),期中方法a()是定義在接口中的,由類A來實現(xiàn),這是一個雙向調(diào)用的過程凌净。

//定義接口
public interface OnItemClickListener{
    void onItemClick(int position);
}
//設(shè)置傳遞接口類實現(xiàn)對象的方法
private OnItemClickListeneronItemClickListener;
    public void setOnItemClickListener(OnItemClickListener onItemClickListener){
    this.onItemClickListener = onItemClickListener;
}
//條目的監(jiān)聽事件
holder.itemView.setOnClickListener(new View.OnClickListener(){
    @Override
    public void onClick(View){
    onItemClickListener.onItemClick(position);
  }
});
3.3 RecyclerView多布局1:banner+recycleview

①RecyclerView基本使用
②定義類型常量
③重寫獲取條目根據(jù)位置分類的方法(getItemViewType)
④重寫onCreateViewHolder悲龟,根據(jù)類型創(chuàng)建不同的布局
⑤重寫onBindViewHolder,根據(jù)不同類型加載不同數(shù)據(jù)

  • 注意:
    ①獲取條目總數(shù)(list.size()+1)
    ②onBindViewHolder:獲取列表條目數(shù)據(jù)的時候(position-1)
    3.RecyclerView與ListView的對比
    RecyclerView與ListView不同點

ListView:

①繼承BaseAdapter冰寻,需要重寫四個方法
②自定義ViewHolder與convertView的優(yōu)化(判斷是否為null)须教;
③可以直接使用item的點擊事件
④不用單獨設(shè)置分隔線
⑤不可以定向刷新某一條數(shù)據(jù)

RecyclerView:

①繼承RecyclerView.Adapter與RecyclerView.ViewHolder
②必須使用viewholder,封裝了view的復(fù)用
③設(shè)置LayoutManager,以及l(fā)ayout的布局效果
④點擊事件可以使用給控件設(shè)置點擊事件斩芭,也可以自定義點擊事件
⑤可以自定義繪制分隔線
⑥可以定向刷新某一條數(shù)據(jù)notifyItemChanged等方法
⑦可以自定義item刪除增加的動畫效果

3.4 RecyclerView多布局2:奇數(shù)位置左圖右文字+偶數(shù)位置左文字右圖片

①RecyclerView基本使用
②定義類型常量
③重寫獲取條目根據(jù)位置分類的方法(getItemViewType)
④重寫onCreateViewHolder轻腺,根據(jù)類型創(chuàng)建不同的布局
⑤重寫onBindViewHolder,根據(jù)不同類型加載不同數(shù)據(jù)

  • 注意:不需要注意索引
3.5 RecyclerView通過接口回調(diào)實現(xiàn)點擊事件

①在adapter中定義一個內(nèi)部接口划乖,內(nèi)部接口定義一個方法贬养,方法參數(shù)是我們需要的返回的值;
②在adapter定義借口變量琴庵,并設(shè)置set方法误算;
③在onBindViewholder()中,給條目做一個點擊事件
④在fragment或者activity對象調(diào)用點擊時間即可

3.6 RecyclerView下拉刷新上拉加載更多

①添加依賴
(implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0')
②在布局中添加刷新控件并找控件

<com.scwang.smartrefresh.layout.SmartRefreshLayout
   android:id="@+id/srl"
   android:layout_width="match_parent"
   android:layout_height="wrap_content">
      //下拉刷新
     < com.scwang.smartrefresh.layout.header.ClassicHeader
          android:layout_width="match_parent"
          android:layout_height="match_parent">
      //上拉加載更多
     <com.scwang.smartrefresh.layout.footer.ClassicsFooter
          android:layout_width="match_parent"
          android:layout_height="wrap_content">

</com.scwang.smartrefresh.layout.SmartRefreshLayout>

③給刷新控件添加加載更多迷殿、下拉刷新添加監(jiān)聽儿礼,監(jiān)聽中寫具體代碼

//監(jiān)聽
srl.setOnRefreshLoadMoreListener(this);
//上拉加載更多
@Override
public void onLoadMore(@NonNull RefreshLayout refreshLayout){
       page++;
      //數(shù)據(jù)源
      initData();
}
//下拉刷新
@Override
    public void onRefresh(@NonNull RefreshLayout refreshLayout) {
        page = 1;
        if (list != null && list.size() > 0) {
            list.clear();
            initData();
        }

④刷新完畢列表,關(guān)閉SmartRefreshLayout頭和腳
srl.finishRefresh();
srl.finishLoadMore();

4 Fragment

4.1 Fragment的基本使用:

一贪庙、靜態(tài)創(chuàng)建fragment
①創(chuàng)建一個fragment
②創(chuàng)建布局蜘犁,把①中的fragment添加到布局中

  • 注意:
    ①必須有設(shè)置id,否則會報錯:Caused by: java.lang.IllegalArgumentException: Binary XML file line #9: Must specify unique android:id, android:tag, or have a parent with an id for com.anfly.fragmentr.AFragment
    ②布局中必須添加屬性name止邮,值給fragment全名

4.2 動態(tài)添加fragment(五步)

        //獲取碎片管理器
        FragmentManager fm = getSupportFragmentManager();

        //開啟事務(wù)
        FragmentTransaction fragmentTransaction = fm.beginTransaction();

        //獲取fragment對象
        AFragment aFragment = new AFragment();

        //替換容器中內(nèi)容
        fragmentTransaction.replace(R.id.fl_container, aFragment);

        //提交事務(wù)
        fragmentTransaction.commit();

4.3 Transaction常用方法

①add 添加
②remove 移除
③replace 替換
④hide 隱藏
⑤show 顯示
⑥attach 重建view視圖这橙,附加到UI上并顯示
⑦detach 會將view從UI中移除,和remove()不同,此時fragment的狀態(tài)依然由FragmentManager維護(hù)
⑧commit 提交事務(wù)

4.4 fragment生命周期

①onAttach() 當(dāng)Fragment與Activity發(fā)生關(guān)聯(lián)時調(diào)用
②onCreate()
③onCreateView() 創(chuàng)建該Fragment的視圖
④onActivityCreated() 當(dāng)Activity的onCreate方法返回時調(diào)用
⑤onStart()
⑥onResume()
⑦onPause()
⑧onStop()
⑨onDestroyView() 與onCreateView想對應(yīng),當(dāng)該Fragment的視圖被移除時調(diào)用
⑩onDestroy()
?onDetach() 與onAttach相對應(yīng)导披,當(dāng)Fragment與Activity關(guān)聯(lián)被取消時調(diào)用

4.5 fragment傳遞數(shù)據(jù)到activity

①獲取activity對象屈扎,調(diào)方法

//獲取getActivity(),強(qiáng)轉(zhuǎn)成MainActivity
MainActivity activity = (MainActivity) getActivity();
activity.getMsgFromFramgent("我是來自fragment的數(shù)據(jù)");

② 接口回調(diào)傳遞數(shù)據(jù)
Java接口與接口回調(diào)在Android中的使用

③通過fragment的有參構(gòu)造傳遞數(shù)據(jù)(不推薦)

4.6 activity傳遞數(shù)據(jù)到fragment

①通過bundle方式傳值
activity中:

AFragment aFragment = new AFragment();
Bundle bundle = new Bundle();
bundle.putString("a", "我是來自activity的數(shù)據(jù)");
aFragment.setArguments(bundle);

fragment中:

Bundle bundle = getArguments();
String a = bundle.getString("a");

4.7 fragment與fragment之間傳遞數(shù)據(jù)

①通過構(gòu)造方式傳值(不推薦)
②通過FragmentManager找到對應(yīng)id或者Tag的Fragment撩匕,然后獲取里面的數(shù)據(jù)或者方法
③通過它們所在的Activity作為橋梁鹰晨,可以使用getActivity()或者接口回調(diào),達(dá)到獲取另一個Fragment數(shù)據(jù)的目的

4.8 RedioGroup底部導(dǎo)航結(jié)合Fragment切換

//創(chuàng)建布局找控件
fl_container = (FrameLayout) findViewById(R. id.fl_ container);
rb_a = (RadioButton) findViewById(R.id.rb_a);
rb_b = (RadioButton) findViewById(R.id.rb_b);
rg = (RadioGroup) findViewById(R. id.rg);

//獲取碎片管理器
fm = getSupportFragmentManager();
//開啟一個事物
FragmentTransaction fragmentTransaction = fm. beginTransaction();

aFragment = new AFragment();
bFragment = new BFragment();
//添加fragment并提交事務(wù)
fragmentTransaction. replace(R.id.fl_container, aFragment). replace(R.id.fl_container, bFragment)
        .hide(bFragment).show(aFragment).commit();

//給RedioGroup設(shè)置監(jiān)聽并通過switch case顯示和隱藏fragment
rg. set0nCheckedChangeListener(new RadioGroup . OnCheckedChangeListener() (
      @Override
      public void onCheckedChanged(RadioGroup group, int checkedId) {
          switch (checkedId) {
                case R.id.rb_a:
                     fm.beginTransaction().show( aFragment).hide(bFragment).commit();
                     break;
                case R.id.rb_b:
                     fm.beginTransaction().show( bFragment).hide(aFragment).commit();
                     break;
          }
     }
]);

五 ViewPager

5.1 ViewPager+tablayout

①創(chuàng)建布局并找控件
②獲取數(shù)據(jù)集合(存放圖片的集合)
創(chuàng)建適配器(四個方法):

//數(shù)量
getCount()
//判斷添加的識圖是否是當(dāng)前的view
isViewFronObject()
//
instantiateItem()
//
destroyItem()

④設(shè)置適配器

5.2 Viewpager結(jié)合Fragment實現(xiàn)導(dǎo)航

①創(chuàng)建布局找控件
②獲取fragment的集合fragments
創(chuàng)建適配器:
FragmentStatePagerAdapter和FragmentPagerAdapter的區(qū)別(布局多的用加state,
不知道的可以用加state,兩個內(nèi)部方法一樣)
④設(shè)置適配器

5.3 Banner使用詳情

官方網(wǎng)站
Banner使用詳情

/**
 * banner使用
 * 1.添加依賴(implementation 'com.youth.banner:banner:1.4.10')
 * 2.創(chuàng)建布局并找控件
 * 3.獲取網(wǎng)數(shù)據(jù)
 * 4.banner設(shè)置圖片集合并調(diào)用start()方法
 */
 runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            ArrayList<String> images = new ArrayList<>();
                            ArrayList<String> titles = new ArrayList<>();
                            for (int i = 0; i < bannerBean.getData().size(); i++) {
                                images.add(bannerBean.getData().get(i).getImagePath());
                                titles.add(bannerBean.getData().get(i).getTitle());
                            }
                                //設(shè)置圖片集合
                        banner.setImages(images)
                                //設(shè)置圖片加載器
                                .setImageLoader(new ImageLoader() {
                                    @Override
                                    public void displayImage(Context context, Object path, ImageView imageView) {
                                         Glide.with(context).load(path).into(imageView);
                                    }
                                 })
                                //設(shè)置標(biāo)題 直接設(shè)置無效必須設(shè)置BannerStyle
                                .setBannerTitles(titles)
                                //設(shè)置banner樣式
                                .setBannerStyle(BannerConfig.NUM_INDICATOR_TITLE)
                                //設(shè)置banner動畫
                                .setBannerAnimation(Transformer.DepthPage)
                                //設(shè)置間隔時間
                                .setDelayTime(500)
                                //啟動輪播
                                .start();
                        }
                    });

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();

5.4 TVF

①創(chuàng)建布局找控件

vp = (ViewPager) findViewById(R.id.vp);
tab = (TabLayout) findViewById(R.id.tab);

②創(chuàng)建兩個集合:fragments和titles
③創(chuàng)建適配器:

public class MyViewpagerAdapter extends FragmentPagerAdapter {
       ArrayList<PageFragment> pageFragmentList;
      public MyViewpagerAdapter(FragmentManager fm, List<PageFragment> pageFragmentList) {
           super(fm);
           this.pageFragmentList = pageFragmentList;
      }
      @Override
      public Fragment getItem(int i) {
           return pageFragmentList.get(i);
      }
      @Override
      public int getCount() {
           return pageFragmentList.size();
      }
}

④ 設(shè)置適配器
⑤TV結(jié)合:tab.settupWithViewPager(vp);
⑥設(shè)置圖片選擇器:tab.getTabAt(0).setIcon();

5.5 TVF涉及到的懶加載(為了避免頁面預(yù)加載)

//重寫過時方法setUserVisibleHint
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    //判斷頁面是否可見
    if (isVisibleToUser) {
          //如果頁面可見加載數(shù)據(jù)
          initData();
    } else {
        if (list != null && list.size > 0) {
            list. clear();
        }
    }
 }

六 彈窗

6.1 Popupwindow

//加載pop的布局
View view = LayoutInflater .from(this). inflate(R.layout.pop1, root: null);
//創(chuàng)建PopupWindow 對象
PopupWindow pop = new PopupWindow(view, ViewGroup. LayoutParams . WRAP_ CONTENT, ViewGroup . LayoutParam . WRAP_ CONTENT);
//聚焦 如果想在pop上編輯框需要設(shè)置該屬性
pop.setFocusable(true);
//pop進(jìn)出場動畫
pop.setAnimationStyle(R.style.pop_animation);

//想要實現(xiàn)點擊外消失需要設(shè)置一個背景
pop.setBackgroundDrawable(new colorDrawable);
//點擊范圍外消失
pop.setOutsideTouchable(true);

//設(shè)置全屏陰影
backgroundAlpha(0.5f);
//把pop設(shè)置到控件上
//pop.showAsDropDown(tv_ address, 0, 0);
//把pop設(shè)置到布局上
pop.showAtLocation(cl, Gravity.CONTENT, 0, 0);

//設(shè)置全屏陰影
private void backgroundAlpha(float alpha) {
    Window window = getWindow();
    WindowManager. LayoutParams attributes = window . getAttributes( );
    attributes.alpha = alpha;
    window. setAttributes(attributes );
}

//pop監(jiān)聽
pop.setOnDi smissListener new PopupWindow . OnDismissListener() {
    @Override
    public void onDismiss() {
        //恢復(fù)透明度
        backgroundAlpha(1f);
    }
});

//style文件
<style name= "pop_ animation">
//進(jìn)場動畫
<item name="android windowEnterAnimation">@anim/anim_ enter</item>
//出場動畫
<item name="android :windowExitAnimation">@anim/anim_ eixt</item>
</style>

//進(jìn)場動畫
<?xml version="1.0" encoding="utf-8"?>
<set xmlns :android= "http://schemas.android.com/apk/res/android"
android : duration="1500">
<alpha
android : fromAlpha="0"
android:toAlpha="1.0" />
<translate
android : fromXDelta="100%p"
android : fromYDelta="100%p"
android: toXDelta="0"
android :toYDelta="0" />
</set>

//出場動畫
<?xml version="1.0" encoding="utf-8"?>
<set xmlns :android= "http://schemas.android.com/apk/res/android"
android : duration="1500">
<alpha
android : fromAlpha="1.0"
android:toAlpha="0" />
<translate
android : fromXDelta="0"
android : fromYDelta="0"
android: toXDelta="100%p"
android :toYDelta="100%p" />
</set>

七 通知

7.1Notification 通知

//創(chuàng)建通知管理器
NotificationManager nm = (NotificationManager) getSystemService (Context.NOTIFICATION_SERVICE);
//兼容O系統(tǒng):Build.VERSION.SDK_INT得到當(dāng)前手機(jī)的版本
String channelId = "1";
String channelName = "lu";
if (Build.VERSION.SDK INT >= Build.VERSION_CODES.O) {
    NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT);
    channel.enableLights(true);
    channel.setLightColor(Color.RED);
    nm.createNotificationChannel(channe);
}
//延時意圖
Intent intent = new Intent(this, Main2Activity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 100, intent, PendingIntent.FLAG_UPDATE_CURRENT);

//創(chuàng)建通知對象
Notification notification = new NotificationCompat.Builder(this, channelId)
        //通知三要素圖標(biāo)止毕,標(biāo)題模蜡,內(nèi)容
        .setSmallIcon(R.mipmap.ic_Launcher round)
        .setContentTitle("標(biāo)題")
        .setContentText("內(nèi)容")
         //設(shè)置延時意圖
        .setContentIntent(pendingIntent)
        .build();
//發(fā)送通知
nm.notify(hd: 1, notification);

八 權(quán)限

8.1 分類:

①普通權(quán)限:不需要動態(tài)獲取
②危險權(quán)限:需要動態(tài)獲取

8.2 九大危險權(quán)限

3C 3S L M P
①CALENDAR 日歷
②CAMERA 相機(jī)
③CONTACTA 聯(lián)系人

④SEMSORS 傳感器
⑤SMS 短信
⑥STORAGE 存儲

⑦LOCATION 位置
⑧MICROPHONE 麥克風(fēng)
⑨PHONE 電話

8.3 如何動態(tài)的獲取權(quán)限

①在清單文件里添加打電話權(quán)限
<uses-permission android:name="android.permission.CALL_PHONE"/>
②檢查權(quán)限

//檢查是否授權(quán)
private void checkPhonePermission(){
      if (ActivityCompat . checkSelfPermission(this, Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED){
          callPhone();
      } else{
          //如果沒有授權(quán)請求該權(quán)限
          ActivityCompat.requestPermissions(this, new String[](Manifest.permission. CALL_PHONE), 100);
      }
 }  
//請求權(quán)限的結(jié)果
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestcode, permissions, grantResults);
    switch(requestCode){
       case 100:
          if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
               callPhone();
          } else {
              Toast.makeText(MainActivity.this, "授權(quán)失敗", Toast.LENGTH_SHORT).show();
          }
          break;
    }
//打電話
private void callPhone() {
    Intent intent = new Intent(Intent.ACTION_CALL);
    intent.setData(Uri.parse("tel:10086"));
    startActivity(intent);
}

8.4 通過第三方框架獲取權(quán)限

①添加依賴
implementation 'com.github.dfqin:grantor:2.5'
②使用

private void authorityGranter() {
     PermissionsUtil.requestPermission(this, new PermissionListener() {
         @Override
         public void permissionGranted(@NonNull String[] permission){
            callPhone();
         }
         @Override
         public void permissionDenied(@NonNull String[] permission) {
            Toast.makeText(MainActivity.this,"授權(quán)失敗", Toast.LENGTH_SHORT).show();
     }, Manifest.permission.CALL_PHONE);
}

九 內(nèi)容提供者

9.1 內(nèi)容提供者步驟

①創(chuàng)建內(nèi)容提供者
new→Other→Content Provider
(1)URI格式 Main里面的全類名+.內(nèi)容提供者類名
(2)手動創(chuàng)建內(nèi)容提供者:自定義一個類繼承自ContentProvider,并重寫方法
②在清單文件里注冊

<provider
android:name=".ClContentProvider"
android:authorities="com.lulu.contentproviderr.ClContentProvider"
android:enabled="true"
android:exported="true/>

③創(chuàng)建SQL數(shù)據(jù)庫 繼承自 SQLitemOpenHelper 并且建庫建表
④在內(nèi)容提供者里面的重寫onCreate中獲取數(shù)據(jù)庫對象并返回對象扁凛,并補齊里面的增刪改查方法

⑤創(chuàng)建第二個類contentresolver

//獲取內(nèi)容解析器
ContentResolver contentResolver=getContentResolver();
//獲取URI(通用資源標(biāo)識符)
Uri uri = Uri.parse("content://+清單文件中的authoriries+/+庫名");

// insert 插入方法
ContentValues contentValues = new ContentValues();
contentValues.put("數(shù)據(jù)庫字段", "內(nèi)容");
contentResolver.insert(uri, contentValues);
  • 常用Uri:

短信:Telephony.Sms.CONTENT_URI
通訊錄: ContactsContract.CommonDataKinds.Phone.CONTENT_URI
圖片:MediaStore.Images.Media.EXTERNAL_CONTENT_URI
音頻:MediaStore.Audio.Media.ENTERNAL_CONTENT_URI
視頻:MediaStpre.Video.Media.ENTERNAL_CONTENT_URI

十 Service

10.1 Service生命周期

①startService生命周期:
onCreate()(開啟服務(wù))-→onStartCommand()(服務(wù)運行)-→onDestory()(停止服務(wù))
②bindService生命周期:
onCreate()(開啟服務(wù))-→onBind()(綁定服務(wù))-→onUnbind(解綁服務(wù))-→onDestory(停止服務(wù))

10.2 startService和bindService區(qū)別

1.啟動服務(wù)中使用StartService()方法來進(jìn)行方法的調(diào)用忍疾,調(diào)用者和服務(wù)之間沒有聯(lián)系,即使調(diào)用者退出了谨朝,服務(wù)依然在進(jìn)行,onCreate()- >onStartCommand()->onDestroy()卤妒,注意其中沒有onStart()甥绿,主要是被onStartCommand()方法給取代了,onStart方法不推薦使用了则披。

2.綁定服務(wù)中使用bindService()方法來綁定服務(wù)共缕,調(diào)用者和綁定者綁在一起,調(diào)用者一旦退出服務(wù)也就終止了onCreate()->onBind()->onUnbind()->onDestroy()士复。

10.3 Activity和Service之間的數(shù)據(jù)傳遞

1.數(shù)據(jù)從Activity和到Service

intent方式:startService和bindService都可以

2.數(shù)據(jù)從Activity到Service

IBinder方式:bindService

3.數(shù)據(jù)從Service到Activity

接口回調(diào)和廣播

十二.音樂播放器

12.1 MediaPlayer創(chuàng)建方式

① 使用 new MediaPlayer 對象的方式
MediaPlayer mp = new MediaPlayer();
② 使用create的方式
MediaPlayer mp = MediaPlayer.create(this,R.raw.test);

12.2 四種資源

① 用戶在應(yīng)用中事先自帶的resource資源

MediaPlayer.create(this, R.raw.test);

② 存儲在SD卡或其他文件路徑下的媒體文件

mp.setDataSource("/sdcard/test.mp3");

③ 網(wǎng)絡(luò)上的媒體文件

mp.setDataSource("[http://music.163.com/song/media/outer/url?id=139894.mp3](https://links.jianshu.com/go?to=http%3A%2F%2Fmusic.163.com%2Fsong%2Fmedia%2Fouter%2Furl%3Fid%3D139894.mp3)");

④ assets目錄下文件

AssetManager assets=getAssets();
    try {
          AssetFileDescriptor assetFileDescriptor = assets.openFd("qinghuaci.mp3");
          player.setDataSource(assetFileDescriptor.getFileDescriptor(), assetFileDescriptor.getStartOffset(), assetFileDescriptor.getLength());
          player.prepare();
          player.start();
         } catch(IOException e) {
          e.printStackTrace();
     }

12.3 assets和raw資源文件夾的區(qū)別:

res/raw不可以有目錄图谷,而assets則可以有目錄結(jié)構(gòu),也就是assets目錄下可以再建立文件夾

12.4 結(jié)合SeekBar實現(xiàn)拖動播放音樂功能

//創(chuàng)建seekbar布局
//seekbar設(shè)置監(jiān)聽阱洪,在停止拖動中player.seekTo(seekBar.getProgress());

//更新seekbar:
private void updataProgress(){
    new Thread(newRunnable(){
        @Override
        public void run(){
             while(player.isPlaying()){
                 try{
                     Thread.sleep(1000);
                     seekbar_mp.setMax(player.getDuration());
                     seekbar_mp.setProgress(player.getCurrentPosition());
                     }catch(Exceptione){
                     e.printStackTrace();
                   }
              }
         }
    }).start();
}

12.5 結(jié)合RecyclerView實現(xiàn)音樂播放上一首蜓萄,下一首功能

①使用ContentResolver+recyclerview展示音樂列表
②條目點擊事件播放對應(yīng)的音樂
③點擊上一首、下一首

private void next(){
    if(positon < list.size()-1){
            positon++;
        }else{
            positon = 0;
        }
     player(list.get(positon).getPath());
}

private void pre(){
    if(positon > 0){
       positon--;
      }else{
      positon = list.size()-1;
    }
    player(list.get(positon).getPath());
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
禁止轉(zhuǎn)載澄峰,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者。
  • 序言:七十年代末辟犀,一起剝皮案震驚了整個濱河市俏竞,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌堂竟,老刑警劉巖魂毁,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異出嘹,居然都是意外死亡席楚,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進(jìn)店門税稼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來烦秩,“玉大人,你說我怎么就攤上這事郎仆≈混簦” “怎么了?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵扰肌,是天一觀的道長抛寝。 經(jīng)常有香客問我,道長曙旭,這世上最難降的妖魔是什么盗舰? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮桂躏,結(jié)果婚禮上钻趋,老公的妹妹穿的比我還像新娘。我一直安慰自己沼头,他們只是感情好爷绘,可當(dāng)我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布书劝。 她就那樣靜靜地躺著,像睡著了一般土至。 火紅的嫁衣襯著肌膚如雪购对。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天陶因,我揣著相機(jī)與錄音骡苞,去河邊找鬼。 笑死楷扬,一個胖子當(dāng)著我的面吹牛解幽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播烘苹,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼躲株,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了镣衡?” 一聲冷哼從身側(cè)響起霜定,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎廊鸥,沒想到半個月后望浩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡惰说,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年磨德,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吆视。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡典挑,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出揩环,到底是詐尸還是另有隱情搔弄,我是刑警寧澤,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布丰滑,位于F島的核電站顾犹,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏褒墨。R本人自食惡果不足惜炫刷,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望郁妈。 院中可真熱鬧浑玛,春花似錦、人聲如沸噩咪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至涨享,卻和暖如春筋搏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背厕隧。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工奔脐, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人吁讨。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓髓迎,卻偏偏與公主長得像,于是被迫代替她去往敵國和親建丧。 傳聞我的和親對象是個殘疾皇子排龄,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 前言 ①方法:思路+案例、預(yù)習(xí)思路②補充知識點:debug翎朱、代碼規(guī)范涣雕、約束布局③學(xué)生講課:三四節(jié)課學(xué)生講課(學(xué)委-...
    Anwfly閱讀 1,034評論 0 6
  • 1, 二級列表(ExpandableListView) ①創(chuàng)建布局闭翩,找控件②獲取數(shù)據(jù):死數(shù)據(jù)、網(wǎng)絡(luò)數(shù)據(jù)③創(chuàng)建適配器...
    一只易拉寶閱讀 198評論 0 0
  • 1.二級列表ExpandableListView (1).創(chuàng)建布局迄埃,找控件 (2).獲取數(shù)據(jù):死數(shù)據(jù)疗韵,網(wǎng)絡(luò)數(shù)據(jù) (...
    孫_慧_雯閱讀 351評論 0 0
  • 隨著卡尼暗示5月加息并非板上釘釘蕉汪,英鎊多頭的熱情退卻。市場擔(dān)心卡尼次日凌晨的講話將再度打壓英鎊逞怨。不過者疤,包括法農(nóng)銀行...
    雷老冇閱讀 217評論 0 0
  • 流程圖 Excel輸入image.png Switch / caseimage.png Excel輸出image....
    千客閱讀 879評論 0 0