中級思路

前言

①方法:思路+案例、預(yù)習(xí)思路
②補充知識點:debug、代碼規(guī)范、約束布局
③學(xué)生講課:三四節(jié)課學(xué)生講課(學(xué)委--組長--組員):前一天通知,沒有就題庫
④小組PK:
提問搶答加分
檢查作業(yè)給對應(yīng)組加分
成為主持人的給對應(yīng)組加分

image.png

題庫

1.側(cè)滑、音樂、tvf、rv單布局、elv+點擊(√)
2.側(cè)滑、rv+刷新+點擊、pop、通知+延時意圖、選項菜單
3.側(cè)滑、tvf、多布局、打電話、webview
4.側(cè)滑、tvf、項目、刷新、webview
5.vp導(dǎo)航、tvf、banner+rv多布局、多布局(需要修改)
6.導(dǎo)航、tvf、九宮格+banner、二級列表、webview
7.側(cè)滑、tvf、rv多布局、選項菜單、pop、相冊跳轉(zhuǎn)替換圖片、service實現(xiàn)音樂播放
8.tvf、rv+banner多布局、選項菜單、數(shù)據(jù)庫、上下文菜單、pop、通知
9.側(cè)滑、tvf、banner+rv多布局、選項菜單、pop、點擊頭像替換圖片
10、tvf、二級列表、側(cè)滑菜單、toobar、cardview、項目

50個面試題
每天講解十五個面試題(一節(jié)課),剩余的時間學(xué)生記憶
4月2日:項目搭建,主要側(cè)滑和toobar
4月3日:題庫4、10,主要項目
4月7日:題庫1、3、6,主要音樂和九宮格、打電話
4月8日:題庫2、8,主要pop和通知(數(shù)據(jù)庫不講)
4月9日:題庫7、9,主要相冊替換和服務(wù)播放音樂
4月10日:題庫5、8,主要數(shù)據(jù)庫
4月13日:帶領(lǐng)大家做終極題1-15(給定時間學(xué)生練習(xí))
4月14日:帶領(lǐng)大家做終極題16-25

一、列表

  1. 二級列表(ExpandableListView)
    ①創(chuàng)建布局,找控件
    ②獲取數(shù)據(jù):死數(shù)據(jù)、網(wǎng)絡(luò)數(shù)據(jù)
    創(chuàng)建適配器:10個方法要掌握
    ④設(shè)置適配器
    ⑤父項、子項點擊事件
    ⑥基本屬性

  2. Listview手動、自動加載更多
    (1)Listview

①創(chuàng)建布局,找控件
②獲取網(wǎng)絡(luò)數(shù)據(jù)
③創(chuàng)建適配器:兩個優(yōu)化(必會):convertView復(fù)用,避免重復(fù)找控件
④設(shè)置適配器

(2)Listview手動加載更多

①創(chuàng)建布局,找控件
②獲取網(wǎng)絡(luò)數(shù)據(jù)
③創(chuàng)建適配器:兩個優(yōu)化(必會)
④設(shè)置適配器
⑤給Listview添加一個footer
⑥點擊footer中button加載更多:page++,獲取數(shù)據(jù)

(3)Listview自動加載更多

①創(chuàng)建布局,找控件
②獲取網(wǎng)絡(luò)數(shù)據(jù)
③創(chuàng)建適配器:兩個優(yōu)化(必會)
④設(shè)置適配器
⑤定義一個變量isBottom表示是否滑到底部
⑥Listview設(shè)置滑動監(jiān)聽

lv.setOnScrollListener(new AbsListView.OnScrollListener() {
            /**
             * 滑動狀態(tài)發(fā)生改變:如果滑到底部,加載更多,修改isBottom值
             * @param view
             * @param scrollState
             * //scrollState 有三種類型
             * 1.SCROLL_STATE_IDLE 手指未觸摸屏幕,且屏幕靜止
             * 2.SCROLL_STATE_TOUCH_SCROLL 手指未離開屏幕滑動
             * 3.SCROLL_STATE_FLING 手指使勁滑動屏幕,然后手指離開屏幕,屏幕仍在滾動
             */
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                switch (scrollState) {
                    case SCROLL_STATE_IDLE:
                        if (isBottom) {
                            page++;
                            initData();
                            isBottom = false;
                        }
                        break;
                }
            }
            /**
             * 滑動監(jiān)聽,判斷是否滑動底部,返回isBottom具體值
             * @param view
             * @param firstVisibleItem:可見頁面第一個條目小標(biāo)
             * @param visibleItemCount:可見頁面數(shù)據(jù)個數(shù)
             * @param totalItemCount:條目總數(shù)
             */
            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                if (firstVisibleItem + visibleItemCount == totalItemCount && totalItemCount > 0) {
                    isBottom = true;
                } else {
                    isBottom = false;
                }
            }
        });

二、菜單

  1. 側(cè)滑菜單
    ①添加依賴
    ②創(chuàng)建布局:DrawerLayout、NavigationView(三個屬性、menu)
    ③設(shè)置actionbar:toolbar設(shè)置標(biāo)題、logo、關(guān)聯(lián)toobar和側(cè)滑菜單
    ④監(jiān)聽事件:頭部監(jiān)聽、側(cè)滑菜單監(jiān)聽、DrawerLayout、代買開關(guān)側(cè)滑菜單
    ⑤沉浸式狀態(tài)欄

  2. 選項菜單
    ①創(chuàng)建選項菜單(onCreateOptionsMenu):兩種方式-代碼和menu(showAsAction)
    ②選項菜單的點擊事件(onOptionsItemSelected):switch

  3. 上下文菜單
    ①注冊上下文菜單:registerForContextMenu()
    ②創(chuàng)建上下文菜單:onCreateContextMenu()
    ③上下文菜單點擊事件:onContextItemSelected()

  • 注意區(qū)別:
    OptionsMenu是整個界面共用,ContextMenu是注冊給某個組件,此組件擁有此菜單,沒有注冊的組件沒此菜單。

  • 補充:fragment怎么顯示選項菜單??

三、RecyclerView

  1. RecyclerView基本使用
    ①添加依賴(版本問題注意)
    ②創(chuàng)建布局(寬高必須是充滿的)
    ③找控件
    ④設(shè)置布局管理器(三種顯示方式:線性布局、網(wǎng)格布局、瀑布流布局)
    ⑤獲取數(shù)據(jù)(切換子線程的方法)
    創(chuàng)建適配器-- 重寫三個,通過接口回調(diào)實現(xiàn)點擊事件
    ⑦設(shè)置適配器

  2. RecyclerView多布局一:list+banner
    ① RecyclerView基本使用
    ②定義類型常量
    ③重寫方法getItemViewType()根據(jù)位置返回不同類型
    ④重寫oncreateViewHolder()根據(jù)不同類型加載不同的布局
    ⑤重寫onBindViewHolder()根據(jù)不用類型加載不同數(shù)據(jù)

  • 注意
    ①獲取條目總數(shù):list.size()+1
    onBindViewHolder:獲取別表條目數(shù)據(jù)的時候,position-1
  1. RecyclerView多布局二:奇數(shù)位置左圖右文字+偶數(shù)位置左文字右圖片
    ① RecyclerView基本使用(看6)
    ②定義類型常量
    ③重寫方法getItemViewType()根據(jù)位置返回不同類型
    ④重寫oncreateViewHolder()根據(jù)不同類型加載不同的布局
    ⑤重寫onBindViewHolder()根據(jù)不用類型加載不同數(shù)據(jù)
  • 注意:沒有7中注意
  1. RecyclerView通過接口回調(diào)實現(xiàn)點擊事件
    ①在adapter定義一個內(nèi)部接口,內(nèi)部接口定義一個方法,方法參數(shù)是我們需要返回值的;
    ②在adapter定義接口變量,并設(shè)置set方法
    ③在onBindVIewholder()中,給條目做一個點擊事件
    ④在fragment或者activity中,使用adapter對象調(diào)用點擊事件即可

  2. RecyclerView添加刷新
    ①添加依賴
    ②在布局中添加刷新的控件并找控件
    ③給刷新控件添加加載更多、下拉刷細(xì)膩添加監(jiān)聽,監(jiān)聽中寫具體代碼
    ④刷新完畢列表,關(guān)閉SmartRefreshLayout頭和腳。

四、fragment

  1. 靜態(tài)添加fragment
    ①創(chuàng)建一個fragment
    ②創(chuàng)建布局,把①中的fragment放到布局中
  • 注意:
    ①必須要有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全類名
  1. 動態(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();
  1. Transaction常用方法
    ①add
    ②remove
    ③replace
    ④hide
    ⑤show
    ⑥attach
    ⑦detach
    ⑧commit

  2. fragment生命周期
    ①onAttach()
    ②onCreate()
    ③onCreateView()
    ④onActivityCreated()
    ⑤onStart()
    ⑥onResume()
    ⑦onPause()
    ⑧onStop()
    ⑨onDestroyView()
    ⑩onDestroy()
    ?onDetach()

  3. fragment傳遞數(shù)據(jù)到activity
    ①獲取activity對象,直接調(diào)用方法

MainActivity activity = (MainActivity) getActivity();
activity.getMsgFromFramgent("我是來自fragment的數(shù)據(jù)");

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

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

  1. 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");
  1. fragment與fragment之間傳遞數(shù)據(jù)
    ①通過構(gòu)造方式傳值(不推薦)
    ②通過FragmentManager找到對應(yīng)Id或者Tag的Framgment,然后獲取里面的數(shù)據(jù)或方法
    ③通過它們所在的Activity作為橋梁,可以使用getActivity()或者接口回調(diào),達(dá)到獲取另一個Fragment數(shù)據(jù)的目的.

  2. RadioGroup底部導(dǎo)航結(jié)合Fragmentr切換

五、ViewPager+tablayout

  1. ViewPager結(jié)合view實現(xiàn)導(dǎo)航
    ①創(chuàng)建布局找控件
    ②獲取數(shù)據(jù)集合
    創(chuàng)建適配器:
getCount()
isViewFromObject()  
instantiateItem()
destroyItem()

④設(shè)置適配器

  1. Viewpager結(jié)合Fragment實現(xiàn)導(dǎo)航
    ①創(chuàng)建布局找控件
    ②獲取fragment的集合fragments
    創(chuàng)建適配器:FragmentStatePagerAdapter和FragmentPagerAdapter區(qū)別以及內(nèi)部方法
    ④設(shè)置適配器

  2. Banner開源框架
    官方

banner
.setBannerStyle(BannerConfig.NUM_INDICATOR_TITLE)//設(shè)置風(fēng)格
.setImages(images)//設(shè)置圖片集合
.setBannerAnimation(Transformer.DepthPage)//設(shè)置動畫
.setBannerTitles(titles)//直接添加無效,必須設(shè)置BannerStyle
.setImageLoader(new GlideImageLoader())//圖片加載器
.start();
  1. Tablayout
    ①屬性

  2. TVF
    ①創(chuàng)建布局找控件:TV
    ②創(chuàng)建兩個集合:fragments和titles
    ③創(chuàng)建適配器:四個方法(包含一個構(gòu)造)
    ④設(shè)置適配器
    ⑤TV結(jié)合:tab.setupWithViewPager(vp);
    ⑥設(shè)置圖片選擇器tab.getTabAt(0).setIcon()

  3. TVF涉及到的懶加載 -- 為了避免預(yù)加載

@Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isVisibleToUser) {
            initData();
        } else {
            if (list != null && list.size > 0) {
                list.clear();
            }
        }
    }

六、PopupWindow

①創(chuàng)建PopupWindow布局
②創(chuàng)建PopupWindow對象,用三個參數(shù)的構(gòu)造
③PopupWindow四種顯示方式
④聚焦:EditText能輸入內(nèi)容
⑤點擊范圍外關(guān)閉PopupWindow
⑥全屏陰影,PopupWindow點擊消失監(jiān)聽
⑦進(jìn)出場動畫

七、Notification

①獲取通知管理器getSystemService
②兼容O版以上系統(tǒng)
③獲取通知對象(構(gòu)建者模式):必要屬性有三項
④用通知管理器發(fā)送通知
⑤延時意圖:intent、pendingIntent、setContentIntent
⑥通知提示:聲音、震動、呼吸燈、全部

八、權(quán)限

  1. 分類
    ①普通權(quán)限:不需要動態(tài)獲取
    ②危險權(quán)限:需要動態(tài)獲取
  2. 危險權(quán)限分類
    3CSLMP
  3. 如何動態(tài)獲取權(quán)限
    ①在清單列表寫上需要的全下你
    ②檢查是否授權(quán)
    如果授權(quán) -> 操作
    如果沒有授權(quán) -> 請求權(quán)限
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED) {
            callPhone();
        } else {
            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;
        }
    }
  1. 通過框架獲取危險權(quán)限
    ①添加依賴implementation 'com.github.dfqin:grantor:2.5'
    ②使用
 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)容提供者

  1. ContentProvider
    ①創(chuàng)建一個數(shù)據(jù)庫及一張表
    ②自定義ContentProvider繼承自ContentProvider,重寫方法
  2. ContentResolver
    ①獲取ContentResolver
    ②獲取uri:Uri.parse("content://"+authorities+/+path)
Uri  uri = Uri.parse("content://com.anfly.contentproviderr.ClContentProvider/cl");

3.ContentResolver讀取短信、通訊錄、圖片、音頻、視頻
①動態(tài)獲取危險全新
②獲取ContentResolver對象contentResolver
③contentResolver調(diào)用query()方法查詢相關(guān)內(nèi)容

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

十、Service

  1. service概述、應(yīng)用場景
  2. startService生命周期
  3. bindService生命周期
  4. startService和bindService區(qū)別
  5. Activity和Service之間的數(shù)據(jù)傳遞
    ①數(shù)據(jù)從Activity和到Service
    intent方式:startService和bindService都可以
    ②數(shù)據(jù)從Activity到Service
    IBinder方式:bindService
    ③數(shù)據(jù)從Service到Activity
    接口回調(diào)和廣播

十一、音樂播放器

  1. MediaPlayer創(chuàng)建方式
    MediaPlayer mp = new MediaPlayer();
    MediaPlayer mp = MediaPlayer.create(this, R.raw.test);
  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");
    ④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();
        }
  1. assets 和 raw 資源文件夾區(qū)別
  2. 結(jié)合SeekBar實現(xiàn)拖動播放音樂功能
    ①創(chuàng)建seekbar布局
    ②seekbar設(shè)置監(jiān)聽,在停止拖動中player.seekTo(seekBar.getProgress());
    ③更新seekbar:
 private void updataProgress() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (player.isPlaying()) {
                    try {
                        Thread.sleep(1000);
                        seekbar_mp.setMax(player.getDuration());
                        seekbar_mp.setProgress(player.getCurrentPosition());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }
  1. 結(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());
    }

  1. 結(jié)合Service實現(xiàn)后臺音樂播放功能
    ①創(chuàng)建一個服務(wù)AudioService
    ②服務(wù)中創(chuàng)建內(nèi)部類AudioBinder,類中有一個方法返回服務(wù)類
    ③在onCreate()初始化MediaPlayer對象
    ④創(chuàng)建一系列關(guān)于mp的方法:播放、暫停、繼續(xù)、停止、拖動
    ⑤在AudioActivity中綁定服務(wù),返回服務(wù)類的對象
    ⑥按鈕點擊事件:通過服務(wù)類對象調(diào)用其方法實現(xiàn)音頻播放
    ⑦seekbar進(jìn)度改變監(jiān)聽,把進(jìn)度傳給mp
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 二級列表(ExpandableListView) ①創(chuàng)建布局,找控件 ②獲取數(shù)據(jù):死數(shù)據(jù)、網(wǎng)絡(luò)數(shù)據(jù) ③創(chuàng)建適配器:...
    俗野_9628閱讀 263評論 0 0
  • 1.ExpandableListView (二級列表) ①創(chuàng)建布局 找控件②獲取數(shù)據(jù) (死數(shù)據(jù) ,網(wǎng)絡(luò)數(shù)據(jù))③創(chuàng)建...
    傾都幽夢閱讀 417評論 0 0
  • 一 二級列表(ExpandableListView) 1.1 死數(shù)據(jù)步驟: ①創(chuàng)建布局找控件②數(shù)據(jù)源(兩個集合:g...
    Brilliancess閱讀 654評論 0 5
  • 如果需要原文檔(因文體限制,部分表格無法呈現(xiàn))請聯(lián)系QQ1769090563 本文由中醫(yī)仲景協(xié)會整理收集 《內(nèi)經(jīng)選...
    陶墨閱讀 35,573評論 0 33
  • 更多分享:www.cherylgood.cn 介紹 OpenCV提供了兩個程序可以訓(xùn)練自己的級聯(lián)分類器: open...
    Angels_安杰閱讀 7,136評論 0 3

友情鏈接更多精彩內(nèi)容