今日,看到群里朋友发的一部分面试题,决定把这这些面试题的答案写下来,以下: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 著做权归做者全部,转载请联系做者得到受权,并标注“简书做者”。