今日,看到羣裏朋友發的一部分面試題,決定把這這些面試題的答案寫下來,以下:java
一、ListView怎麼和ScrollView兼容? ok
二、ViewPager無限輪播圖片
三、out of memory內存溢出怎麼解決
四、三級緩存如何實現
五、登陸時怎麼保存用戶名密碼實現下次自動登陸
六、若是sp只存儲用戶名,好比三個用戶都存在sp裏,取出來怎麼取?存進去怎麼存?你怎麼區分
七、大家登陸就只有登陸成功和登陸失敗嗎?難道沒有重連機制?斷網了之後又有網了從新來到登陸界面怎麼登陸?
八、怎麼保持在線狀態
九、toobar,actionbar玩的轉不?
十、include標籤總會吧?
十一、webview配置會吧
十二、CoordinatorLayout和recycleview會吧
1三、tab用actionbar就能實現你知道嗎?
1四、你知道Listview裏有Button就點不動了你知道嗎 ok
1五、簡單的動畫你會嗎?哪怕是運用到activity的出現與退出,以及屬性動畫
1六、view的點擊事件跟dialog的點擊事件很容易引錯包
1七、集合List<>爲何動態增加?它有默認長度的,有時候用他步入指定好長度的數組
1八、下載時,異步任務和子線程他倆的區別
1九、recycleview代替listview,gridview,瀑布流三種模式切換自如
20、listview怎麼優化 ok
2一、fragment的倆個適配器的區別
2二、MVC,MVP
2三、註解?findviewbyid
2四、socket,http,xmpp,rstp這些協議
2五、oom內存泄漏android
今天決定先寫ListView相關的,我把上述的一、1四、20放到一塊兒來講,也就是本篇文章,其餘的稍後有時間持續更新,你們若是對此感興趣的話,請關注我,咱們一塊兒學習。web
================================================面試
咱們知道,有些時候咱們須要在ListView外層嵌套一層ScrollView,代碼以下:數組
<ScrollView android:id="@+id/scrollview" android:layout_width="match_parent" android:layout_height="wrap_content"> <ListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="wrap_content"></ListView> </ScrollView>
只要稍微有點經驗的人都知道這是會出現什麼問題,沒錯,就是「Listview不能顯示正常的條目,只顯示一條或二條」,這是怎麼回事呢?這是由於:因爲listView在scrollView中沒法正確計算它的大小, 故只顯示一行。
當目前爲止,我知道的針對這一問題的解決辦法有:緩存
activity_list_view_scroll_view_test.xml: <merge xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.art.demo.ListViewScrollViewTestActivity"> <ScrollView android:id="@+id/scrollview" android:layout_width="match_parent" android:layout_height="wrap_content"> <com.art.demo.WrapperListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="wrap_content"/> </ScrollView> </merge> WrapperListView.java: public class WrapperListView extends ListView { public WrapperListView(Context context) { super(context); } public WrapperListView(Context context, AttributeSet attrs) { super(context, attrs); } public WrapperListView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public WrapperListView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } /** * 重寫該方法,達到使ListView適應ScrollView的效果 */ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); } } ListViewScrollViewTestActivity.java: public class ListViewScrollViewTestActivity extends AppCompatActivity { private ScrollView scrollView; private WrapperListView listView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_list_view_scroll_view_test); scrollView = (ScrollView) findViewById(R.id.scrollView); listView = (WrapperListView) findViewById(R.id.listview); initListVeiw(); } private void initListVeiw() { List<String> list = new ArrayList<>(); for (int i = 0; i < 20; i++) { list.add("第 " + i + " 條"); } listView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list)); } } 另外,哪位大神能夠告訴我在代碼塊(```)中,怎麼給某一行加粗,或者作一些其餘明顯標記??????????????
只須要在setAdapter以後調用以下方法便可:網絡
public void setListViewHeightBasedOnChildren(ListView listView) { // 獲取ListView對應的Adapter ListAdapter listAdapter = listView.getAdapter(); if (listAdapter == null) { return; } int totalHeight = 0; for (int i = 0, len = listAdapter.getCount(); i < len; i++) { // listAdapter.getCount()返回數據項的數目 View listItem = listAdapter.getView(i, null, listView); // 計算子項View 的寬高 listItem.measure(0, 0); // 統計全部子項的總高度 totalHeight += listItem.getMeasuredHeight(); } ViewGroup.LayoutParams params = listView.getLayoutParams(); params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)); // listView.getDividerHeight()獲取子項間分隔符佔用的高度 // params.height最後獲得整個ListView完整顯示須要的高度 listView.setLayoutParams(params); }
另外,這時,這時最好給ListView以外嵌套一層LinearLayout,否則有時候這種方法會失效,以下:app
<merge xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.art.demo.ListViewScrollViewTestActivity"> <ScrollView android:id="@+id/scrollview" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="@+id/listview" android:layout_width="fill_parent" android:layout_height="match_parent" android:background="#FFF4F4F4" android:dividerHeight="0.0dip" android:fadingEdge="vertical" /> </LinearLayout> </ScrollView> </merge>
能夠肯定的是:這種方式能夠改變ListView的高度,可是,還有一個嚴重的問題就是listview的數據是可變更的,除非你能正確的寫出listview的高度,不然這種方式就是個雞肋。
以下:異步
<ScrollView android:id="@+id/scrollview" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="@+id/listview" android:layout_width="fill_parent" android:layout_height="300dip" android:background="#FFF4F4F4" android:dividerHeight="0.0dip" android:fadingEdge="vertical" /> </LinearLayout> </ScrollView>
某些狀況下,其實咱們能夠徹底避免ScrollView嵌套Listview,好比使用listview的addHeader() 函數來實現預期效果或者利用佈局的特性達到預期效果,固然,具體怎麼用,只有在開發中慢慢琢磨,慢慢總結了.socket
至此,關於「ListView怎麼和ScrollView兼容」這個問題就算是回答完了,若是有不明白的地方能夠問我,一樣,那裏有錯誤也歡迎你們指出,真的不勝感激。
接下來要說的就是!!!!!
關於Listview的優化,只要面試過的人,我相信都對這個題很熟悉,無論有沒有人問過你這個題,我想你本身也必定準備過,不然,嘿嘿!!!!!並且網上也一搜一大把這裏就簡單提幾個主要的:
1)、convertView複用,對convetView進行判空,當convertView不爲空時重複使用,爲空則初始化,從而減小了不少沒必要要的View的建立
2)定義一個ViewHolder,封裝Listview Item條目中全部的組件,將convetView的tag設置爲ViewHolder,不爲空時經過ViewHolder的屬性獲取對應組件便可
3)、當ListView加載數據量較大時能夠採用分頁加載和圖片異步加載(關於Listview分頁加載和圖片異步加載思路請看接下來的文章內容)
下面就是關於Listview的一些相關拓展
解決辦法有兩種:
方法一:把套在裏面的ListVew 不讓獲取焦點便可。listview.setFocusable(false);注意:在xml佈局裏面設置android:focusable=「false」不生效
方法二:myScrollView.smoothScrollTo(0,0);
實現OnScrollListener 接口重寫onScrollStateChanged 和onScroll方法,
使用onscroll方法實現」滑動「後處理檢查是否還有新的記錄,若是有,調用 addFooterView,添加記錄到adapter, adapter調notifyDataSetChanged 更新數據;若是沒有記錄了,把自定義的mFooterView去掉。使用onScrollStateChanged能夠檢測是否滾到最後一行且中止滾動而後執行加載
在listview子佈局裏面寫,能夠解決焦點失去的問題
android:descendantFocusability="blocksDescendants"
1.先從內存緩存中獲取圖片顯示(內存緩衝)
2.獲取不到的話從SD卡里獲取(SD卡緩衝,,從SD卡獲取圖片是放在子線程裏執行的,不然快速滑屏的話會不夠流暢)
3.都獲取不到的話從網絡下載圖片並保存到SD卡同時加入內存並顯示(視狀況看是否要顯示)
緣由是button強制獲取了item的焦點,只要設置button的focusable爲false便可。
繼承自BaseAdapter實現裏面的方法,listView在開始繪製的時候,系統首先調用getCount()函數,根據他的返回值獲得listView的長度,而後根據這個長度,調用getView()逐一繪製每一行。若是你的getCount()返回值是0的話,列表將不顯示一樣return 1,就只顯示一行。系統顯示列表時,首先實例化一個適配器(這裏將實例化自定義的適配器)。當手動完成適配時,必 須手動映射數據,這須要重寫getView()方法。系統在繪製列表的每一行的時候將調用此方法。getView()有三個參數,position表示將顯示的是第幾行,covertView是從佈局文件中inflate來的 佈局。咱們用LayoutInflater的方法將定義好的main.xml文件提取成View實例用來顯示。
而後 將xml文件中的各個組件實例化(簡單的findViewById()方法)。這樣即可以將數據對應到各個組件上了。可是按鈕爲了響應點擊事件,須要爲它添加點擊監聽器,這樣就能捕獲點擊事件。至此一個自定 義的listView就完成了,如今讓咱們回過頭重新審視這個過程。系統要繪製ListView了,
他首先得到 要繪製的這個列表的長度,而後開始繪製第一行,怎麼繪製呢?
調用getView()函數。在這個函數裏面 首先得到一個View(其實是一個ViewGroup),而後再實例並設置各個組件,顯示之。好了,繪製完這一行了。那 再繪製下一行,直到繪完爲止。在實際的運行過程當中會發現listView的每一行沒有焦點了,這是由於Button搶奪了listView的焦點,只要佈局文件中將Button設置爲沒有焦點就OK了。
一般實現分頁加載有兩種方式,一種是在ListView底部設置一個按鈕,用戶點擊即加載。另外一種是當用戶滑動到底部時自動加載。
在ListView底部設置一個按鈕,用戶點擊即加載實現思路:
// 加上底部View,注意要放在setAdapter方法前 ListView.addFooterView(moreView); bt.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { pg.setVisibility(View.VISIBLE);// 將進度條可見 bt.setVisibility(View.GONE);// 按鈕不可見 handler.postDelayed(new Runnable() { @Override public void run() { loadMoreDate();// 加載更多數據 bt.setVisibility(View.VISIBLE); pg.setVisibility(View.GONE); mSimpleAdapter.notifyDataSetChanged();// 通知listView刷新數據 } }, 2000); } });
當用戶滑動到底部時自動加載實現思路:
實現OnScrollListener 接口重寫onScrollStateChanged 和onScroll方法,使用onscroll方法實現」滑動「後處理檢查是否還有新的記錄,若是有,添加記錄到adapter, adapter調用 notifyDataSetChanged 更新數據;若是沒有記錄了,則再也不加載數據。使用onScrollStateChanged能夠檢測是否滾到最後一行且中止滾動而後執行加載.
這不是Android的優化,而是Java提倡的優化,
若是聲明成員類不要求訪問外圍實例,就要始終把static修飾符放在它的聲明中,使它成爲靜態成員類,而不是非靜態成員類。
由於非靜態成員類的實例會包含一個額外的指向外圍對象的引用,保存這份引用要消耗時間和空間,而且致使外圍類實例符合垃圾回收時仍然被保留。若是沒有外圍實例的狀況下,也須要分配實例,就不能使用非靜態成員類,由於非靜態成員類的實例必需要有一個外圍實例。
文/乆_丩(簡書做者) 原文連接:http://www.jianshu.com/p/b7741023bc6f 著做權歸做者全部,轉載請聯繫做者得到受權,並標註「簡書做者」。