请写出3个Android布局,一起撸一波干货集中营练练手Android(三)布局+实现篇
MPGankIO 布局篇
整個App到了這里就開始準備開始實現邏輯啦,有沒有點小期待
后續如果有需要可以爬一波包包通緝令的數據O(∩_∩)O~~
我們的布局采用5.0之后的新布局控件
1.CardView
CardView特別的屬性如下:
android:cardCornerRadius:在布局中設置card圓角的大小
CardView.setRadius:在代碼中設置card圓角的大小
android:cardBackgroundColor:在布局中設置card背景的顏色
android:elevation:設置陰影的大小
card_view:cardElevation 陰影的大小
card_view:cardMaxElevation 陰影最大高度
card_view:cardCornerRadius 卡片的圓角大小
card_view:contentPadding 卡片內容于邊距的間隔
card_view:contentPaddingBottom
card_view:contentPaddingTop
card_view:contentPaddingLeft
card_view:contentPaddingRight
card_view:contentPaddingStart
card_view:contentPaddingEnd
card_view:cardUseCompatPadding 設置內邊距,V21+的版本和之前的版本仍舊具有一樣的計算方式
**card_view:cardPreventConrerOverlap
在V20和之前的版本中添加內邊距,這個屬性為了防止內容和邊角的重疊**
我們要使用這個CardView來做卡片式的列表
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:foreground="?android:attr/selectableItemBackground"
android:orientation="vertical"
app:contentPadding="5dp">
android:layout_width="match_parent"
android:layout_height="match_parent">
android:id="@id/tv_title"
style="@style/txt_normal_style"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:ellipsize="end"
android:gravity="start"
android:maxLines="3"
android:text="標題"
android:textSize="16sp"
/>
android:id="@id/tv_name"
style="@style/txt_normal_style"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_below="@id/tv_title"
android:layout_marginTop="10dp"
android:gravity="bottom"
android:text="作者"
android:textColor="@color/colorPrimary"/>
android:id="@id/tv_publishtime"
style="@style/txt_normal_style"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_below="@id/tv_title"
android:layout_marginTop="10dp"
android:gravity="bottom"
android:text="發表時間"/>
CardView 大部分適用于 listView 或者recyclerView的item中。
2.RecyclerView
RecyclerView與ListView原理是類似的:都是僅僅維護少量的View并且可以展示大量的數據集。RecyclerView用以下兩種方式簡化了數據的展示和處理:
使用LayoutManager來確定每一個item的排列方式。
為增加和刪除項目提供默認的動畫效果。
你也可以定義你自己的LayoutManager和添加刪除動畫,SDK中默認包含了三種布局
1. 橫向布局(LinearLayoutManager)
2. Grid布局(GridLayoutManager)
3. 瀑布流布局(StaggeredGridLayoutManager)
Adapter:使用RecyclerView之前,你需要一個繼承自RecyclerView.Adapter的適配器,作用是將數據與每一個item的界面進行綁定。
LayoutManager:用來確定每一個item如何進行排列擺放,何時展示和隱藏。回收或重用一個View的時候,
LayoutManager會向適配器請求新的數據來替換舊的數據,這種機制避免了創建過多的View和頻繁的調用findViewById方法(與ListView原理類似)。
總而言之就相當于ListView封裝后再抽象,使item更加靈活
項目中我使用的是XRecyclerView,是封裝了上拉刷新和下拉加載的一個庫,非常好用還有挺多的加載動畫可以切換,使用的方法也很簡單,哈哈,偷懶!! 不都是說為了不要重復造輪子嘛~你懂的
3.Fragment
這個應該不用多講了相信大家都會的
4.代碼附上
MainFragment.java 這個就是為了在主頁將一些數據初始化為了給TypeFragment拿到類型數據
為什么使用FragmentStateAdapter而不用FragmentPagerAdapter是因為viewpager頁數比較多
FragmentStateAdatper的機制是空置的時候將其銷毀釋放內存,而FragmentPagerAdapter是將其dettach
因此選用FragmentSteteAdapter
GankViewPagerAdapter.java
public class GankViewPagerAdapter extends FragmentStatePagerAdapter {
private List mFragments;
private List mTitles;
public GankViewPagerAdapter(FragmentManager fm, List fragments, List titles) {
super(fm);
this.mFragments = fragments;
this.mTitles = titles;
}
@Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
@Override
public int getCount() {
return mFragments.size();
}
@Override
public CharSequence getPageTitle(int position) {
return mTitles.get(position);
}
}
大家如果之前理解過MVP架構應該就會發現我調用的方式啦!
TypeFragment.java 核心模塊
public class TypeFragment extends BaseMvpFragment implements
TypeFragmentView {
private static final String ARG_PARAM1 = "type";
@BindView(R.id.rv_list)
XRecyclerView rvList;
private String mCategory;
private View rootView;
private GankTypeCardAdapter mGankTypeCardAdapter;
private List mDatas;
private int curPage = 1;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mCategory = getArguments().getString(ARG_PARAM1);
}
initVariables();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_type, container, false);
ButterKnife.bind(this, rootView);
resetDatas();
initViews();
return rootView;
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(ARG_PARAM1, mCategory);
}
@Override
public void onViewStateRestored(Bundle savedInstanceState) {
super.onViewStateRestored(savedInstanceState);
if (savedInstanceState != null) {
mCategory = ConvertUtil.toString(savedInstanceState.getString(ARG_PARAM1), "");//避免為NULL
}
}
@Override
public void initVariables() {
mDatas = new ArrayList<>();
}
@Override
public void initViews() {
initRecyclerView();
presenter.getTypeGankList();
}
private void initRecyclerView() {
rvList.setPullRefreshEnabled(true);
rvList.setLoadingMoreEnabled(true);
rvList.setLoadingListener(new XRecyclerView.LoadingListener() {
@Override
public void onRefresh() {
resetDatas();
presenter.getTypeGankList();
}
@Override
public void onLoadMore() {
presenter.getTypeGankList();
}
});
}
@Override
protected TypePresenter initPresenter() {
return new TypePresenter();
}
public static TypeFragment newInstance(String type) {
TypeFragment fragment = new TypeFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, type);
fragment.setArguments(args);
return fragment;
}
@Override
public String getCategory() {
return mCategory;
}
@Override
public int getCurPage() {
return curPage;
}
@Override
public void addOnePage() {
curPage++;
}
@Override
public void makeUpDatas(List datas) {
mDatas.addAll(datas);
}
@Override
public void notifyAdapter() {
if (mGankTypeCardAdapter == null) {
mGankTypeCardAdapter = new GankTypeCardAdapter(mActivity, mDatas);
rvList.setLayoutManager(new LinearLayoutManager(mActivity));
rvList.setAdapter(mGankTypeCardAdapter);
}
// TODO: 16/8/19 //此處可以優化成動畫效果以及item逐個優化不需要整個重新排列
mGankTypeCardAdapter.notifyDataSetChanged();
rvList.refreshComplete();
rvList.loadMoreComplete();
}
@Override
public void resetDatas() {
curPage = 1;
mDatas.clear();
if (mGankTypeCardAdapter != null) {
mGankTypeCardAdapter.notifyDataSetChanged();
}
}
@Override
public void onDestroyView() {
mGankTypeCardAdapter = null;
super.onDestroyView();
}
}
最后就是P中調用V啦 就是傳說中的解耦
到此基本上的請求列表功能結束啦,下一篇最終章就是列表點擊事件和鏈接的內容頁面!
有問題可以來我博客或者簡書反饋,謝謝大家的停留在這里時間
總結
以上是生活随笔為你收集整理的请写出3个Android布局,一起撸一波干货集中营练练手Android(三)布局+实现篇的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: scala 获取数组中元素_从Scala
- 下一篇: android sina oauth2.