Android开发框架Collection,Android社招面经分享

前言

其实一开始我考虑的是阿里的,因为那里有认识的人,希望通过内推可以顺利进入大厂,但是却被面试官一连串问题,完虐!这时候秋招已经过半,后来在牛客上看了很多牛友面经,也加了很多交流群,受到了很多朋友的提点,今天终于轮到我还愿啦,拿到了北京教育业务客户端的 offer,总结一下自己的面经和复习历程,顺便谈谈我的一些感受,给各位牛友提供一些参考。

先说一下我的情况吧,现在就读杭州电子科技大学,本科山东农业大学,本硕都是计算机。老区山东临沂人,平常喜欢拍照、旅游、看电影和基友一起打游戏。

break;
case MultiItem.TYPE_IMG:
baseViewHolder.setImageResource(R.id.ivImg, multiItem.getRes());
break;
case MultiItem.TYPE_TEXT_IMG:
baseViewHolder.setImageResource(R.id.ivImg, multiItem.getRes());
baseViewHolder.setText(R.id.titleTv, multiItem.getTitle());
break;

}

}

4.添加拖拽、滑动删除

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WOobZZmq-1649914548331)(https://user-gold-cdn.xitu.io/2020/2/29/1708f5daef719975?imageslim)]

局限:只针对RecyclerView,对本框架封装的PullToRefreshRecyclerView会出现混乱。
①BaseRecyclerViewAdapter和BaseRecyclerViewMultiItemAdapter都已经封装支持拖拽、滑动,适配器只需要根据需求继承其中一个即可。
②框架提供了一个BaseRecycleItemTouchHelper,对于普通的左右滑动删除、拖拽已经实现,如果想自定义可以继承BaseRecycleItemTouchHelper类,再重写相对应的方法进行实现。
④在Activity/Fragment中需要实现以下代码:

ItemTouchHelper.Callback callback=new BaseRecycleItemTouchHelper(dragAndDeleteAdapter);
ItemTouchHelper itemTouchHelper=new ItemTouchHelper(callback);
itemTouchHelper.attachToRecyclerView(mRecyclerView);

⑤BaseRecyclerViewAdapter.OnDragAndDeleteListener进行操作动作完成之后的回调。

@Override
public void onMoveComplete() {
ToastUtils.showToast(this, “移动操作完成”);
}

@Override
public void onDeleteComplete() {
ToastUtils.showToast(this, “删除操作完成”);
}

四、MVP+RxJava+Retrofit的封装使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YLqiaVKc-1649914548332)(https://user-gold-cdn.xitu.io/2020/2/29/1708f5db05d9cbb8?imageslim)]

1.在使用Retrofit请求网络之前需要进行配置,在框架中提供了了Config配置类

属性 作用
DEBUG 是否为BuildConfig.DEBUG,日志输出需要
CONTEXT 设置Context,必填项
URL_DOMAIN 网络请求的域名,需要以“/”结尾
URL_CACHE 网络缓存地址,需要设置缓存才可以成功
MAX_CACHE_SECONDS 设置OkHttp的缓存机制的最大缓存时间,默认为一天
MAX_MEMORY_SIZE 缓存最大的内存,默认为10M
MClASS 设置网络请求json通用解析类
EXPOSEPARAM Json数据某些字段在没有数据是会不返回来,可通过这个属性设置过滤
USER_CONFIG SharePreference保存的名称
CONNECT_TIMEOUT_SECONDS 请求接口超时设定
READ_TIMEOUT_SECONDS 请求接口超时设定
HEADERS 设置Http全局请求头
SQLITE_DB_NAME 数据库名称
SQLITE_DB_VERSION 数据库版本名
在项目中需要根据项目需要进行配置,在Application中设置

private void config(){
//基本配置
Config.DEBUG= BuildConfig.DEBUG;
Config.CONTEXT=this;
//Retrofit配置
Config.URL_CACHE=AppConfig.URL_CACHE;
Config.MClASS= Result.class;
Config.URL_DOMAIN=“https://api.apiopen.top/”;
//SharePreference配置
Config.USER_CONFIG=“Collection_User”;
Config.SQLITE_DB_VERSION=0;
}

根据项目需要定义一个通用的数据实体类,这是本例通用实体类,这个类需要设置到Applicatin中

public class Result implements Serializable {

private int code;
private String msg;
private T newslist;

public int getCode() {
return code;
}

public void setCode(int code) {
this.code = code;
}

public String getMsg() {
return msg;
}

public void setMsg(String msg) {
this.msg = msg;
}

public T getNewslist() {
return newslist;
}

public void setNewslist(T newslist) {
this.newslist = newslist;
}
}

注意:由于每个项目返回来的json数据格式有所不同,如果Result中代表的字段例如newslist没有内容返回来的时候这个字段需要后台控制不返回,如果不做处理会报解析错误,可以通过设置Config.EXPOSEPARAM属性过滤字段。

2.RxJava+Retrofit+OkHttp

(1)RequestBuilder的设置(网络请求的配置)

属性 作用
ReqType 数据处理的方式,默认DEFAULT_CACHE_LIST,使用到OkHttp缓存的需要需要设置Config.URL_CACHE
NO_CACHE_MODEL 不设置缓存,返回model
NO_CACHE_LIST 不设置缓存,返回list
DEFAULT_CACHE_MODEL 使用Okttp默认缓存,返回model
DEFAULT_CACHE_LIST 使用Okttp默认缓存,返回list
DISK_CACHE_LIST_LIMIT_TIME 限时使用自定义磁盘缓存,返回List
DISK_CACHE_MODEL_LIMIT_TIME 限时使用自定义磁盘缓存,返回model
DISK_CACHE_NO_NETWORK_LIST 自定义磁盘缓存,没有网络返回磁盘缓存,返回List
DISK_CACHE_NO_NETWORK_MODEL 自定义磁盘缓存,没有网络返回磁盘缓存,返回Model
DOWNLOAD_FILE_MODEL 文件下载模式,返回Model
HttpType 网络请求方式,默认DEFAULT_GET
DEFAULT_GET GET请求
DEFAULT_POST POST请求
FIELDMAP_POST 如果请求URL出现中文乱码,可选择这个
JSON_PARAM_POST json格式请求参数
ONE_MULTIPART_POST 上传一张图片
MULTIPLE_MULTIPART_POST 上传多张图片
DOWNLOAD_FILE_GET 下载文件
ReqMode 请求模式,默认ASYNCHRONOUS
ASYNCHRONOUS 异步请求
SYNCHRONIZATION 同步请求
其它参数
setTransformClass 设置请求转化Class
setUrl 设置请求url,如果不设置完全连接则会使用Config.URL_DOMIN进行拼接
setFilePathAndFileName 设置自定义缓存时的路径和文件名
setLimtHours 设置自定义缓存的有效时间
setHeader 设置请求头
setHeaders 设置请求头集合
setHttpTypeAndReqType 设置请求数据类型和请求方式
setImagePath 设置上传图片路径
setImagePaths 设置多张图片路径
isUserCommonClass 设置是否使用公用类转化
setReqMode 设置同步异步

(2)使用模块

RequestBuilder> resultRequestBuilder = new RequestBuilder<>(new RxObservableListener>(mView) {
@Override
public void onNext(Result result) {
mView.refreshUI(result.getResult());
}
});

resultRequestBuilder
.setUrl(ApiUrl.URL_WETCHAT_FEATURED)
.setTransformClass(WeChatNews.class)
.setParam(“page”,page)
.setParam(“type”,“video”)
.setParam(“count”,num);

rxManager.addObserver(DataManager.DataForHttp.httpRequest(resultRequestBuilder));

(3)Retrofit的扩展
如果存在DataManager提供的方法满足不了的请求可以通过RetrofitManager提供的getNoCacheApiService()和getApiService()获得不缓存和缓存的Retrofit,然后通过RxSubscriber进行回调。

Observable observable = RetrofitManager.getNoCacheApiService(ApiService.class)
.getWeChatStr(ApiUrl.URL_WECHAT_HOST + ApiUrl.ACCESS_TOKEN, reqParams);

DisposableObserver observer = observable
.compose(RxSchedulers.io_main())
.subscribeWith(new RxSubscriber() {
@Override
public void _onNext(WeChatAccessToken weChatAccessToken) {
getUserInfo(weChatAccessToken);
}

@Override
public void _onError(NetWorkCodeException.ResponseThrowable responseThrowable) {
showToast(R.string.wx_LoginResultEmpty);
hideLoadingDialog();
finish();
}

@Override
public void _onComplete() {

}
});

rxManager.addObserver(observer);

定义一个ApiService类

public interface ApiService {
/**

  • 微信精选
  • @param url
  • @param map
  • @return
    */
    @GET
    Observable> getWeChatFeaturedNews(@Url String url, @QueryMap Map map);
    }
注意:
(1)RxObservableListener有三个回调方法

void onNext(T result);
void onComplete();
void onError(NetWorkCodeException.ResponseThrowable e);

只会重写onNext方法,其它两个方法可以自行选择重写。
(2)RxObservableListener提供两个构造函数

protected RxObservableListener(BaseView view){
this.mView = view;
}

protected RxObservableListener(BaseView view, String errorMsg){
this.mView = view;
this.mErrorMsg = errorMsg;
}

这两个构造函数主要主要是为了统一处理onError的,如果要自定义错误提醒,则可以选择第二个构造函数。
(3)通过DataManager的网络请求方式会返回来一个DisposableObserver,需要把它通过rxManager.addObserver()添加进CompositeDisposable才能正常执行,方便对网络请求的销毁管理。
(4)如果项目没有统一的解析been类,那么Config的公用类就不用设置了,在Retrofit请求的时候直接setTransformClass指定一个解析类就可以了
(5)如果项目想两种方式共存,那么在请求的时候需要通过setUserCommonClass(false)设置才能不使用统一解析类进行解析
(6)请求的域名已经在Application设置好了,setUrl不需要填完整的url
②要区分清楚接口返回的数据时List还是Model,从而选择对应的ReqType
(7)setRequestParam可以设置参数集合,setParam可以单个设置
(8)使用DISK_CACHE_LIST_LIMIT_TIME/DISK_CACHE_MODEL_LIMIT_TIME这两个显示限时缓存时需要通过setFilePathAndFileName()设置保存路径setLimtHours()设置缓存时间(单位为:小时)
(9)如果要上传单张图片需要用到HttpType.ONE_MULTIPART_POST的请求方式,同时通过RequestBuilder设置MultipartBody.Part

3.MVP

1.写一个Contract类对Presenter和View进行统一管理(View需要实现BaseView,Presenter需要实现BasePresenter

public interface WeChatFeaturedContract {

interface View extends BaseView {
void refreshUI(List newsList);
}

abstract class Presenter extends BasePresenter {
public abstract void requestFeaturedNews(int page, int num);
}

}

2.写一个具体的Presenter类实现WeChatChinaNewsContract.Presenter,在里面做具体的逻辑处理,处理完成再通过mView进行View的处理

3.Activity/Fragment实现IBaseActivity/IBaseFragment以及定义好的WeChatChinaNewsContract.View

4.缺陷:View在使用时需要转化成在具体的子类才能调用相关方法。

5.具体使用可以参照demo

五、DataManager的使用(Http、Sharepreference、SQLite)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HvzdLI7A-1649914548332)(https://user-gold-cdn.xitu.io/2020/2/29/1708f5db149e2266?imageslim)]

(1)DataManager基本属性

属性 作用
DataForSqlite 数据库模块
insert 插入bean数据
insertList 插入List数据
insertListBySync 异步插入List数据
queryByFirstByWhere 根据条件查询
queryAll 查询某个bean类的全部数据
queryAllBySync 异步查询某个bean类的全部数据
queryByFirst 查询某个bean类的第一条数据
delete 根据条件删除数据
deleteAll 删除某个bean类的所有数据
deleteTable 删除数据表
update 更新某个bean类的
queryOfPageByWhere 根据条件分页查询,实体类必须包含PrimaryKey
queryOfPage 分页查询,实体类必须包含PrimaryKey
updateTable 更新数据表,用于增加字段
execQuerySQL Sql语句查询
DataForHttp Http模块
httpRequest 网络请求,传入RequestBuilder
DataForSharePreferences SharePreference模块
saveObject 保存基本类型数据
getObject 获取基本类型数据

(2)DataForSqlite 1.插入一条数据

user=new User();
user.setId(0);
user.setName(“Young1”);
user.setAge(14);
user.setAddress(“山东省”);
user.setStr(“eeeee”);
DataManager.DataForSqlite.insert(user);

showToast(“保存成功”);

2.查询数据

user=DataManager.DataForSqlite.queryByFirst(User.class);
String showContent=“用户Id:”+user.getId()+“\n”+“用户姓名:”+user.getName()+“\n”+“用户年龄:”+user.getAge()+“\n”+“用户地址:”+user.getAddress();
showToast(showContent);

3.批量插入数据(可同步可异步)

List users=new ArrayList<>();
for(int i=0;i<10000;i++){
user=new User();
user.setId(i);
user.setName(“Young1”);
user.setAge(14);
user.setAddress(“广州市”);

users.add(user);
}

DataManager.DataForSqlite.insertListBySync(User.class, users, new SQLiteDataBase.InsertDataCompleteListener() {
@Override
public void onInsertDataComplete(boolean isInsert) {
if(isInsert){
ToastUtils.showToast(getActivity(),“保存成功”);
}else{
ToastUtils.showToast(getActivity(),“保存失败”);
}
}
});

4.bean类的定义

public class User {
@Column(isPrimaryKey =true)
private int id;
private String name;
private int age;
private String address;
private String str;

public String getStr() {
return str;
}

public void setStr(String str) {
this.str = str;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}
}

其中可以通过Column进行注解定义(isPrimaryKey、isNull、isUnique)

5.数据表格变化(只支持增加字段)

  • 修改数据库版本号Config.SQLITE_DB_VERSION,往上递增

  • 在Application中对版本号进行监听,并对数据表进行更新

SQLiteVersionMigrate sqLiteVersionMigrate=new SQLiteVersionMigrate();
sqLiteVersionMigrate.setMigrateListener(new SQLiteVersionMigrate.MigrateListener() {
@Override
public void onMigrate(int oldVersion, int newVersion) {
for (int i=oldVersion;i<=newVersion;i++){
if(i==2){

}

}
}
});

(3)DataForHttp

RequestBuilder> resultRequestBuilder = new RequestBuilder<>(new RxObservableListener>(mView) {
@Override
public void onNext(Result result) {
mView.refreshUI(result.getResult());
}
});

resultRequestBuilder
.setUrl(ApiUrl.URL_WETCHAT_FEATURED)
.setTransformClass(WeChatNews.class)
.setParam(“page”,page)
.setParam(“type”,“video”)
.setParam(“count”,num);

rxManager.addObserver(DataManager.DataForHttp.httpRequest(resultRequestBuilder));

(4)DataForSharePreferences

1.插入基本数据

DataManager.DataForSharePreferences.saveObject(“user”,“这是一条测试的内容”)
ToastUtils.showToast(activity,“保存成功”)

2.查询基本类型数据

val con=DataManager.DataForSharePreferences.getObject(“user”,“”)
ToastUtils.showToast(activity,con)

六.Base的使用

1.为了方便Activity/Fragment设置顶部菜单栏,继承IBaseActivity/IBaseFragment即可显示一个简单的顶部菜单,IBaseFragment的顶部菜单默认隐藏,下面以IBaseActivity的顶部菜单作为例子
属性 作用
isShowSystemActionBar 重写该方法设置实现显示系统ActionBar
isShowCustomActionBar 重写该方法设置显示自定义Bar
setCustomActionBar 重写该方法设置自定义Bar
  • 如果使用默认自定义Bar可通过DefaultDefineActionBarConfig进行相关设置
属性 作用
hideBackBtn 隐藏返回按钮
setBarBackgroundColor 设置Bar的背景颜色
setBarHeight 设置Bar的高度
setTitleColor 设置标题颜色
setTitle 设置标题
setBackClick 设置返回按钮监听
  • 代码使用

defineActionBarConfig .setTitleSize(20f) .setBarHeight(DisplayUtils.dip2px(this,60f)) .setBarBackgroundColor(this,R.color.driver_font) .setTitle(getString(R.string.tab_Indicator_title))

2.使用Fragment实现交互

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WV7c8COz-1649914548333)(https://user-gold-cdn.xitu.io/2020/5/25/172499798b820642?imageslim)]

属性 作用
fragmentLayoutId 设置显示Fragment的根布局id,在Activity中设置
startFragmentForResult(…) 和回调结果跳转
onFragmentResult(…) Fragment的结果回调
setResult(…) onFragmentResult回调的结果设置
startFragment(…) 普通跳转,具体使用查看IBaseActivity
isRootFragment() 判断是否是根Fragment
3.StateView(数据加载页面)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sfhaJsLI-1649914548333)(https://user-gold-cdn.xitu.io/2020/2/29/1708f5db2ac45f72?imageslim)]

属性 作用
STATE_NO_DATA 不显示加载框状态码
STATE_LOADING 加载数据显示状态码
STATE_EMPTY 没有数据显示状态码
STATE_DISCONNECT 没有网络状态码
setOnDisConnectViewListener 点击没有网络图标回调
setOnEmptyViewListener 点击没有没有数据图标回调
showViewByState 设置显示状态
getmEmptyView 获取无数据状态View
布局可设置参数
loadingViewAnimation 设置加载的drawable动画
loadingText 加载时的文本
emptyImage 空布局显示的图片
emptyText 空布局文本
emptyViewRes 设置自定义空布局
disConnectImage 设置断网显示的图片
disConnectText 设置断网显示的文本
tipTextSize 文本字体大小
tipTextColor 文本字体颜色
(1)定义一个通用布局

android:layout_width=“match_parent”
android:layout_height=“match_parent”
android:layout_centerInParent=“true”
android:id=“@+id/state_view”>

(2)添加到Ui页面的layout中
注意:上面的语句添加的layout最外层最好是LinearLayout以及设置为android:orientation=“vertical”
(3)通过以下语句进行状态切换

stateView.showViewByState(StateView.STATE_LOADING);
stateView.showViewByState(StateView.STATE_EMPTY);
stateView.showViewByState(StateView.STATE_NO_DATA);
stateView.showViewByState(StateView.STATE_DISCONNECT);

3.三步实现Permission(权限)设置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wl5hjHjb-1649914548334)(https://user-gold-cdn.xitu.io/2020/2/29/1708f5db2ff3f7ec?imageslim)]

// 项目的必须权限,没有这些权限会影响项目的正常运行
private static final String[] PERMISSIONS = new String[]{
Manifest.permission.READ_SMS,
Manifest.permission.RECEIVE_WAP_PUSH,
Manifest.permission.READ_CONTACTS
};

(2)权限通过PermissionManager管理

permissionManager=PermissionManager.with(this).
setNecessaryPermissions(PERMISSIONS);

permissionManager.requestPermissions();

(3)页面重写onRequestPermissionsResult

//重写
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == PermissionManager.PERMISSION_REQUEST_CODE) {//PERMISSION_REQUEST_CODE为请求权限的请求值
//有必须权限选择了禁止
if (permissionManager.getShouldShowRequestPermissionsCode() == PermissionManager.EXIST_NECESSARY_PERMISSIONS_PROHIBTED) {
ToastUtils.showToast(PermissionActivity.this,“可以在这里设置重新跳出权限请求提示框”);
} //有必须权限选择了禁止不提醒
else if (permissionManager.getShouldShowRequestPermissionsCode() == PermissionManager.EXIST_NECESSARY_PERMISSIONS_PROHIBTED_NOT_REMIND) {
ToastUtils.showToast(PermissionActivity.this,“可以在这里弹出提示框提示去应用设置页开启权限”);
permissionManager.startAppSettings();
}
}
}

注意:如果有需求先判断是否所有权限都已经允许之后再进入主页面可以通过permissionManager.isLackPermission()进行判断,如果返回true则进行权限请求,如果返回false则进入主页面。
  • 多个权限请求如果其中某一个被禁止提醒,会先把没有禁止提醒的权限处理完之后再进行处理。
  • 如果是必要权限被禁止而没有选择禁止提醒退出之后下次会重新请求权限。
  • 如果必要权限被禁止和选择了禁止提醒重新进入页面在onRequestPermissionsResult会重新回调方法。
  • 使用者可以根据onRequestPermissionsResult()方法中返回来的标志PermissionManager.EXIST_NECESSARY_PERMISSIONS_PROHIBTED和PermissionManager.EXIST_NECESSARY_PERMISSIONS_PROHIBTED_NOT_REMIND做出对应的显示和操作(例如弹框提示跳转到设置页面或者toat提示)。

4.提供几种比较常用的Dialog弹框

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z6AqBsok-1649914548334)(https://user-gold-cdn.xitu.io/2020/2/29/1708f5db4d0f872c?imageslim)]

(1)提供的常用的CommonDialog
属性 作用
DIALOG_TEXT_TWO_BUTTON_DEFAULT 默认弹出按钮提示
DIALOG_TEXT_TWO_BUTTON_CUSTOMIZE 自定义弹出按钮提示
DIALOG_LOADING_PROGRASSBAR 默认加载弹框
DIALOG_CHOICE_ITEM 没有数据显示状态码

根据不同的构造函数设置不同的参数

(2)自定义Dialog样式
  • BaseDialogFragment
属性 作用
setContentView 设置弹框布局样式
onViewCreated 初始化完成后的回调,可在此做一些初始化
show(…) 显示弹框
dismiss 弹框销毁
setAllCancelable 点击返回键和外部不可取消
setOnlyBackPressDialogCancel 点击返回键可以取消
setDialogInterval 设置弹框和屏幕两边的间距
setDialogHeight 设置弹框高度
setOnDismissListener 弹框销毁回调
  • 继承BaseDialogFragment,通过setContentView(R.layout.dialog_list)设置弹窗布局。
  • 在提供的onViewCreated方法中进行相应的逻辑设置

5.自定义PopupWindow弹框

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CFbuGMzF-1649914548335)(https://user-gold-cdn.xitu.io/2020/2/29/1708f5db4975a044?imageslim)]

  • BasePopupWindow
属性 作用
BasePopupWindow(Context context) 调用该构造函数默认弹出框铺满全屏
BasePopupWindow(Context context, int w, int h) 自定义弹出框高宽
showPopup 在屏幕中央显示弹框
showPopupAsDropDown 在指定控件底部显示弹框
showPopup 在屏幕中央显示弹框
showPopupAsDropDown 在指定控件底部显示弹框
setShowMaskView 设置是否显示遮层
dismiss 销毁弹出框
getPopupLayoutRes 自定义弹出框的布局文件
getPopupAnimationStyleRes 自定义弹出框的动画文件,不设置动画返回0
  • 继承BasePopupWindow。
  • 通过getPopupLayoutRes(R.layout.xxx)设置弹窗布局。
  • 通过getPopupAnimationStyleRes(R.style.xxx)设置弹窗动画,不需要动画可以设置为0。
  • 如果需要显示遮层,在构造函数通过setShowMaskView(true)设置。

七、CustomView的使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6HaDHz2U-1649914548335)(https://user-gold-cdn.xitu.io/2020/2/29/1708f5db4f6777eb?imageslim)]

1.CommonTabLayout的使用

属性 作用
tab_tabIndicatorWidth 设置下滑线的长度
tab_tabIndicatorHeight 设置下滑线的高度
tab_tabIndicatorColor 下滑线颜色
tab_indicator_marginLeft 设置下滑线外边距
tab_indicator_marginRight 设置下滑线外边距
tab_indicator_marginTop 设置下滑线外边距
tab_indicator_marginBottom 设置下滑线外边距
tab_tabTextColor 没选中字体颜色
tab_tabTextSize 字体大小
tab_tabSelectedTextColor 选中字体颜色
tab_padding 下滑线内边距,block样式时可以通过该属性设置距离
tab_tabBackground Tab 的背景颜色
tab_indicator_corner 下滑线的圆角大小
tab_indicator_gravity(bottom、top 设置下滑线显示的位置,只针对line和triangle
tab_tabMode(scrollable、fixed) Tab的显示模式
tab_indicator_style(line、triangle、block) 下滑线的样式
具体可参照例子使用。

2.OutSideFrameTabLayout的使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u0rlORc0-1649914548336)(https://user-gold-cdn.xitu.io/2020/2/29/1708f5db6501a479?imageslim)]

属性 作用
tab_tabIndicatorColor 设置Tab颜色
tab_indicator_corner 圆角大小
tab_indicator_marginLeft 下滑线外边距
tab_indicator_marginRight 下滑线外边距
tab_indicator_marginTop 下滑线外边距
tab_indicator_marginBottom 下滑线外边距
tab_tabTextColor 没选中字体颜色
tab_tabSelectedTextColor 选中字体颜色
tab_tabTextSize 字体大小
tab_tabSelectedTextColor 选中字体颜色
tab_padding 内边距
tab_bar_color bar的背景颜色
tab_bar_stroke_color 外框的颜色
tab_bar_stroke_width 外框的大小
tab_width bar的长度
具体可参照例子使用。

3.AutoLineLayout的使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vjv2LPzU-1649914548336)(https://user-gold-cdn.xitu.io/2020/2/29/1708f5db6c8450e5?imageslim)]

  • 在外层布局使用AutoLineLayout

android:layout_width=“match_parent”
android:layout_height=“wrap_content”>

4.TagView的使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7QB0c5WO-1649914548336)(https://user-gold-cdn.xitu.io/2020/2/29/1708f5db7160ab8e?imageslim)]

TagViewConfigBuilder
属性 作用
setTitles 设置TagItem内容
setTextSize 设置TagItem字体大小
setTextColor 设置TagItem字体颜色
setTextSelectColor 设置TagItem选择字体颜色
setPaddingLeftAndRight 设置TagIttem左右内边距
setPaddingTopAndBottom 设置TagIttem上下内边距
setMarginAndTopBottom 设置TagItem上下外边距
setMarginLeftAndRight 设置TagItem左右外边距
setackgroudRes 设置background Drawable
setTagViewAlign 设置整体TagItem的Align(LEFT,RIGHT,CENTER)
1.布局

android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:id=“@+id/tagView” />

2.代码设置

String[] list={“werwrw”,“4545465”,“金浩”,“风和日丽”,
“一只蜜蜂叮在挂历上”,“阳光”,“灿烂”,“1+1”,“浏览器”,“玲珑骰子安红豆,入骨相思知不知”};

TagViewConfigBuilder builder=new TagViewConfigBuilder()
.setTitles(list);

tagView.create(builder, new TagView.TagViewPressListener() {
@Override
public void onPress(View view, String title, int position) {
ToastUtils.showToast(TagViewActivity.this,title);
}
});

八、工具类的使用

1.Density(适配不同手机像素)
  • 在Applicaton的onCreate中设置 Density.setDensity(this, 375f)
  • 375f代表设计稿的宽度,以dp为单位,后面需要以f(浮点型)

最后

最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的24套腾讯、字节跳动、阿里、百度2019-2021BAT 面试真题解析,我把大厂面试中常被问到的技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节。

还有 高级架构技术进阶脑图 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

Android 基础知识点

Java 基础知识点

Android 源码相关分析

常见的一些原理性问题

Android开发框架Collection,Android社招面经分享_第1张图片

希望大家在今年一切顺利,进到自己想进的公司,共勉!
烂",“1+1”,“浏览器”,“玲珑骰子安红豆,入骨相思知不知”};

TagViewConfigBuilder builder=new TagViewConfigBuilder()
.setTitles(list);

tagView.create(builder, new TagView.TagViewPressListener() {
@Override
public void onPress(View view, String title, int position) {
ToastUtils.showToast(TagViewActivity.this,title);
}
});

八、工具类的使用

1.Density(适配不同手机像素)
  • 在Applicaton的onCreate中设置 Density.setDensity(this, 375f)
  • 375f代表设计稿的宽度,以dp为单位,后面需要以f(浮点型)

最后

最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的24套腾讯、字节跳动、阿里、百度2019-2021BAT 面试真题解析,我把大厂面试中常被问到的技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节。

还有 高级架构技术进阶脑图 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

Android 基础知识点

Java 基础知识点

Android 源码相关分析

常见的一些原理性问题

[外链图片转存中…(img-KuJjPHpO-1649914548337)]

希望大家在今年一切顺利,进到自己想进的公司,共勉!

你可能感兴趣的:(Android,经验分享,面试,android)