編輯:關於Android編程
AppBarLayout 是繼承LinerLayout實現的一個ViewGroup容器組件,它是為了Material Design設計的App Bar,支持手勢滑動操作。
AppBarLayout必須作為Toolbar的父布局容器,也可以配合CoordinatorLayout一起使用。
ToolBar是谷歌新推出的代替ActionBar的一個標題欄控件,能將背景拓展到狀態欄,依賴包是v7,使用之前先把style中繼承的主題改為NoActionBar;
可以設置”標題”,”副標題”,”Logo”,”NavigationIcon”以及”Menu菜單”,也可以自定義布局;
TextView是一個居中的標題,
fitsSystemWindows實現狀態欄各版本適配方案:
1.Android5.0以上:material design風格,半透明(APP 的內容不被上拉到狀態)
2.Android4.4(kitkat)以上至5.0:全透明(APP 的內容不被上拉到狀態)
3.Android4.4(kitkat)以下:不占據status bar
在Activity中添加代碼即可使用ToolBar;
mToolbar = (Toolbar) findViewById(R.id.toolbar);
tvToolTitle = (TextView) findViewById(R.id.toolbar_title);
tvToolTitle.setText("測試");
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
ToolBar中的菜單布局:
mToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_settings:
break;
default:
break;
}
return true;
}
});
DrawerLayout可以輕松的實現抽屜效果、在DrawerLayout中,第一個子View必須是顯示內容的view,第二個view是抽屜view,設置屬性layout_gravity=”left"right”,表示是從左邊滑出還是右邊滑出。
使用前需添加:
compile 'com.android.support:design:23.3.0'
xml中的布局代碼如下:
<framelayout android:id="@+id/frame_content" android:layout_below="@+id/appbar" android:layout_height="match_parent" android:layout_width="match_parent" android:scrollbars="none" app:layout_behavior="@string/appbar_scrolling_view_behavior">
</framelayout>
第一個布局使用的是Framelayout,可以通過側滑抽屜欄的點擊顯示出不同的Fragment;
而抽屜布局用的是NavigationView,NavigationView需要接收幾個必要的參數、一個用於顯示頭部的布局以及用於顯示選項的菜單布局;可在xml中直接添加布局;
app:headerLayout="@layout/navigation_header"
app:menu="@menu/drawer"
頭部布局xml代碼:
選項菜單布局:
配合ToolBar,在Activity中的使用代碼:
public class MainActivity extends AppCompatActivity implements BackHandledFragment.BackHandlerInterface {
private DrawerLayout mDrawerLayout;
private ActionBarDrawerToggle mDrawerToggle;
private Toolbar mToolbar;
private BackHandledFragment selectedFragment;
private NavigationView mNavigationView;
private TextView tvToolTitle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
tvToolTitle = (TextView) findViewById(R.id.toolbar_title);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolbar, R.string.drawer_open,
R.string.drawer_close);
mDrawerToggle.syncState();
mDrawerLayout.addDrawerListener(mDrawerToggle);
mNavigationView = (NavigationView) findViewById(R.id.navigation_view);
setupDrawerContent(mNavigationView);
switchToBook();
}
private void switchToBook() {
getSupportFragmentManager().beginTransaction().replace(R.id.frame_content, new RecyclerFragment()).commit();
tvToolTitle.setText("測試");
}
private void switchToExample() {
getSupportFragmentManager().beginTransaction().replace(R.id.frame_content, new DayFragment()).commit();
tvToolTitle.setText("測試");
}
private void switchToBlog() {
getSupportFragmentManager().beginTransaction().replace(R.id.frame_content, new BlankFragment()).commit();
tvToolTitle.setText("測試");
}
private void switchToAbout() {
getSupportFragmentManager().beginTransaction().replace(R.id.frame_content, new TimeFragment()).commit();
tvToolTitle.setText("測試");
}
private void setupDrawerContent(NavigationView navigationView) {
navigationView.setNavigationItemSelectedListener(
new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.navigation_item_book:
switchToBook();
break;
case R.id.navigation_item_example:
switchToExample();
break;
case R.id.navigation_item_blog:
switchToBlog();
break;
case R.id.navigation_item_about:
switchToAbout();
break;
}
menuItem.setChecked(true);
mDrawerLayout.closeDrawers();
return true;
}
});
}
@Override
public void setSelectedFragment(BackHandledFragment backHandledFragment) {
this.selectedFragment = backHandledFragment;
}
private long exitTime = 0;
public void doExitApp() {
if ((System.currentTimeMillis() - exitTime) > 2000) {
Toast.makeText(this, R.string.press_again_exit_app, Toast.LENGTH_SHORT).show();
exitTime = System.currentTimeMillis();
} else {
finish();
}
}
@Override
public void onBackPressed() {
if (selectedFragment == null || !selectedFragment.onBackPressed()) {
if (mDrawerLayout.isDrawerOpen(Gravity.LEFT)) {
mDrawerLayout.closeDrawer(Gravity.LEFT);
} else {
doExitApp();
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.test,menu);
return true;
}
}
vc+087XEzOHJ/aOszai5/cno1sPL/Mzhuam1xLK7zaxMYXlvdXRNYW5hZ2Vyo6xJdGVtRGVjb3JhdGlvbiAsIEl0ZW1BbmltYXRvcr/J0tTKtc/Wt+G4u7XEuabE3KOs0sDAtbD8ysd2N6O7PGJyIC8+DQpSZWN5Y2xlclZpZXfSssTcz/FMaXN0Vmlld9K70fnM7bzTSGVhZGVy0tS8sEZvb3RlcqOs0rK/ydLUzai5/WFkZE9uU2Nyb2xsTGlzdGVuZXK9+NDQt9bSs7zT1NijuzxiciAvPg0K0tRSZWN5Y2xlcnZpZXfM7bzTVmlld3BhZ2VyzqpIZWFkZXLOqsD919O21FJlY3ljbGVydmlld7340NC88rWltcTKudPDo6xWaWV3cGFnZXLKudPDtcTKx0dpdEh1YsnPtcTSu7j2v6rUtM/uxL+jrMq1z9bX1LavwtaypbXEQXV0b1Njcm9sbFZpZXdQYWdlcqO7PGJyIC8+DQpHaXRIdWK12Na3zqqjujwvcD4NCjxwcmUgY2xhc3M9"brush:java;">
https://github.com/Trinea/android-auto-scroll-view-pager
Header是通過GitHub上的一個開源項目RecyclerViewHeader,快速為Recyclerview添加Header;
GitHub地址為:
https://github.com/blipinsk/RecyclerViewHeader
添加完依賴包之後即可進行應用。
fragment_recyclerview.xml的代碼:
<framelayout android:layout_height="match_parent" android:layout_width="match_parent" xmlns:android="http://schemas.android.com/apk/res/android">
</framelayout>
recyclerview_item的代碼:
RecyclerAdapter.class的代碼
public class RecyclerAdapter extends RecyclerView.Adapter {
private List list = new ArrayList<>();
private static final int ANIMATED_ITEMS_COUNT = 4;
private Activity context;
private boolean animateItems = false;
private int lastAnimatedPosition = -1;
public RecyclerAdapter(Activity context , List mlist) {
TypedValue mTypedValue = new TypedValue();
context.getTheme().resolveAttribute(R.attr.selectableItemBackground, mTypedValue, true);
list = updateItems(mlist,true);
this.context = context;
}
public class ViewHolder extends RecyclerView.ViewHolder {
public ImageView ivBook;
public int position;
public ViewHolder(View v) {
super(v);
ivBook = (ImageView) v.findViewById(R.id.ivBook);
}
}
private void runEnterAnimation(View view, int position) {
if (!animateItems || position >= ANIMATED_ITEMS_COUNT - 1) {
return;
}
if (position > lastAnimatedPosition) {
lastAnimatedPosition = position;
view.setTranslationY(Utils.getScreenHeight(context));
view.animate()
.translationY(0)
.setStartDelay(100 * position)
.setInterpolator(new DecelerateInterpolator(3.f))
.setDuration(700)
.start();
}
}
public List updateItems(List books, boolean animated) {
List list = new ArrayList<>();
animateItems = animated;
lastAnimatedPosition = -1;
list.addAll(books);
notifyDataSetChanged();
return list;
}
@Override
public RecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recyclerview_item, parent, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
runEnterAnimation(holder.itemView, position);
RecyclerBean recyclerBean = list.get(position);
holder.ivBook.setBackgroundResource(recyclerBean.getImg());
}
@Override
public int getItemCount() {
return list.size();
}
public RecyclerBean getBook(int pos) {
return list.get(pos);
}
public RecyclerItemClickListener.OnItemClickListener onItemClickListener = new RecyclerItemClickListener.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
RecyclerBean book = getBook(position);
Intent intent = new Intent(context, RecyclerDetailActivity.class);
intent.putExtra("book", book);
ActivityOptionsCompat options =
ActivityOptionsCompat.makeSceneTransitionAnimation(context,
view.findViewById(R.id.ivBook),context.getString(R.string.transition_book_img));
ActivityCompat.startActivity(context, intent, options.toBundle());
}
};
}
RecyclerVpAdapter.class的代碼:
public class RecyclerVpAdapter extends FragmentPagerAdapter {
ArrayList list;
FragmentManager fm;
public RecyclerVpAdapter(FragmentManager fm, ArrayList list) {
super(fm);
this.list = list;
this.fm = fm;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Fragment getItem(int arg0) {
return list.get(arg0);
}
}
RecyclerFragment.class中代碼:
RecyclerView mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
mRecyclerView.setHasFixedSize(true);
//ListView形式的列表
// LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
//GirdView形式的列表
GridLayoutManager layoutManager = new GridLayoutManager(getContext(),2);
mRecyclerView.setLayoutManager(layoutManager);
RecyclerViewHeader header = (RecyclerViewHeader) view.findViewById(R.id.header);
AutoScrollViewPager viewPager = (AutoScrollViewPager) header.findViewById(R.id.vp_books);
ArrayList fragmentList = new ArrayList<>();
for (int i = 0; i < vpImgPath.length; i++) {
RecyclerVpFragment recyclerVpFragment = RecyclerVpFragment.newInstance(vpImgPath[i]);
fragmentList.add(recyclerVpFragment);
}
RecyclerVpAdapter bAdapter = new RecyclerVpAdapter(getChildFragmentManager(),fragmentList);
viewPager.setAdapter(bAdapter);
viewPager.setCurrentItem(0);
viewPager.startAutoScroll();
//開啟Viewpager的自動輪播
header.attachTo(mRecyclerView,true);
for (int i = 0; i < title.length; i++) {
RecyclerBean recyclerBean = new RecyclerBean();
recyclerBean.setImg(imgPath[i]);
recyclerBean.setInfo(tvInfo[i]);
recyclerBean.setTitle(title[i]);
recyclerBean.setCatalog(title[i]);
recyclerBean.setAuthor_intro(title[i]);
recyclerBean.setSummary(title[i]);
recyclerBean.setImglarge(imgPath[i]);
mList.add(recyclerBean);
}
mAdapter = new RecyclerAdapter(getActivity(),mList);
//RecyclerView子項的點擊事件
mRecyclerView.addOnItemTouchListener(new RecyclerItemClickListener(getActivity(), mAdapter.onItemClickListener));
mRecyclerView.setAdapter(mAdapter);
上面RecyclerView的item布局裡面,父布局是一個CardView;
CardView繼承FrameLayout,是能在自身之上添加了圓角和陰影效果的一種布局,常常用在RecyclerView、ListView、GirdView的item布局裡面;
比較常用的有這幾個屬性:
app:cardCornerRadius="4dp"
app:cardElevation="10dp"
android:foreground="?android:attr/selectableItemBackground"
(GIF太大,壓縮大小之後,有點兒問題)
CoordinatorLayout,一個從另一層面去控制子view之間觸摸事件的布局,在CoordinatorLayout的布局中使用了Toolbar ,允許你更加自由的自定義其外觀與布局的其余部分融為一體。使用AppBarLayout可以讓你的Toolbar與其他View(比如TabLayout的選項卡)能響應被標記了ScrollingViewBehavior的View的滾動事件。
CollapsingToolbarLayout,可伸縮折疊的Toolbar ,直接添加Toolbar到AppBarLayout可以讓你使用enterAlwaysCollapsed和 exitUntilCollapsedscroll標志,但是無法控制不同元素如何響應collapsing的細節。這裡使用了 CollapsingToolbarLayout的app:layout_collapseMode=”pin”來確保Toolbar在view折疊的時候仍然被固定在屏幕的頂部當你讓CollapsingToolbarLayout和Toolbar在一起使用的時候,title 會在展開的時候自動變得大些,而在折疊的時候讓字體過渡到默認值。
TabLayout 既實現了固定的選項卡(View的寬度平均分配),也實現了可滾動的選項卡(View寬度不固定同時可以橫向滾動)。如果你使用ViewPager在 tab之間橫向切換,你可以直接從PagerAdapter的getPageTitle() 中創建選項卡,然後使用setupWithViewPager()將兩者聯系在一起。它可以使tab的選中事件能更新ViewPager,同時 ViewPager
的頁面改變能更新tab的選中狀態。
注:圖中Activity的啟動效果動畫是通過下面代碼實現的:
ActivityOptionsCompat options =
ActivityOptionsCompat.makeSceneTransitionAnimation(context,
view.findViewById(R.id.ivBook),context.getString(R.string.transition_book_img));
ActivityCompat.startActivity(context, intent, options.toBundle());
使用之前先添加Design的包,即可使用這三個;
activity_appbar_detail.xml主布局代碼:
RecyclerDetailActivity.class代碼:
public class RecyclerDetailActivity extends AppCompatActivity {
private ViewPager mViewPager;
private RecyclerBean mBook;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_appbar_detail);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onBackPressed();
}
});
mBook = (RecyclerBean) getIntent().getSerializableExtra("book");
CollapsingToolbarLayout collapsingToolbar = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
collapsingToolbar.setTitle(mBook.getTitle());
ImageView ivImage = (ImageView) findViewById(R.id.ivImage);
ivImage.setBackgroundResource(mBook.getImglarge());
mViewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(mViewPager);
TabLayout tabLayout = (TabLayout) findViewById(R.id.sliding_tabs);
tabLayout.addTab(tabLayout.newTab().setText("測試"));
tabLayout.addTab(tabLayout.newTab().setText("測試"));
tabLayout.addTab(tabLayout.newTab().setText("測試"));
tabLayout.setupWithViewPager(mViewPager);
}
private void setupViewPager(ViewPager mViewPager) {
MyPagerAdapter adapter = new MyPagerAdapter(getSupportFragmentManager());
adapter.addFragment(DetailFragment.newInstance(mBook.getSummary()), "測試");
adapter.addFragment(DetailFragment.newInstance(mBook.getAuthor_intro()), "測試");
adapter.addFragment(DetailFragment.newInstance(mBook.getCatalog()), "測試");
mViewPager.setAdapter(adapter);
}
static class MyPagerAdapter extends FragmentPagerAdapter {
private final List mFragments = new ArrayList<>();
private final List mFragmentTitles = new ArrayList<>();
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
public void addFragment(Fragment fragment, String title) {
mFragments.add(fragment);
mFragmentTitles.add(title);
}
@Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
@Override
public int getCount() {
return mFragments.size();
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitles.get(position);
}
}
}
TextInputLayout 控件表現得就像LinearLayout 一樣,它是一個容器。TextInputLayout 中只能放一個子元素,和ScrollView有點類似,並且子元素必須是EditText;
TextInputLayout 實現的功能就是當EditText中輸入第一個字母要隱藏hint的時候,TextInputLayout中會出現一個懸浮的標簽來顯示這個hint,還負責一個炫酷的的material 動畫
布局代碼:
布局代碼:
Fragment中的代碼:
public class BlankFragment extends Fragment {
private View view;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_blank, container, false);
final CoordinatorLayout coordinatorLayout = (CoordinatorLayout) view.findViewById(R.id.coordinatorLayout);
FloatingActionButton floatingActionButton = (FloatingActionButton) view.findViewById(R.id.flb_black);
floatingActionButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Snackbar.make(coordinatorLayout,
"Snackbar", Snackbar.LENGTH_LONG)
.setAction("OK", new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(
getActivity(),
"snackbar OK clicked",
Toast.LENGTH_LONG).show();
}
})
.show();
}
});
return view;
}
}
Android打包apk時,有時候需要打各種渠道包,例如 豌豆莢、華為手機市場、小米市場、360市場等,那麼每一種渠道打包時,都需要配置不同的數據元,如果渠道較多,那麼打
Android DragVideo實現播放視頻時任意拖拽DragVideoA Method to Drag the Video When Playing Video一種在
這篇博客主要介紹的是 Android 主流各種機型和各種版本的懸浮窗權限適配,但是由於碎片化的問題,所以在適配方面也無法做到完全的主流機型適配懸浮窗適配懸浮窗適配有兩種方
本文主要介紹Android立體旋轉動畫,或者3D旋轉,下圖是我自己實現的一個界面 立體旋轉分為以下三種: 1.以X軸為軸心旋轉 2.以Y軸為軸心旋轉 3.