目录
3、使用wrap_content、match_parent、layout_weight
一、ViewPager实现导航效果
应用场景:
引导界面、相册多图片预览
多Tab页面、App导航
广告播放展示
注:ListView上下滑动 ViewPager左右滑动
应用背景
viewpager在support.v4包下面
Support包:Google公司在发布一个Android版本后,为了开发者更好的开发又补充发布的包,ViewPager、Fragment都在v4包中。
概念介绍
List<View> || List<Fragment>
PageAdapter || FragmentAdapter
List<View>:视图的列表,通过PageAdapter将视图(页面)和数据联系起来
注:常用快捷键
For循环快捷键 fori
快捷键查询Ctrl+Shift+A
ViewPager常用方法
setCurrentItem
设置当前显示的页面
setOffscreenPageLimit
设置当前页面两侧预加载页面的个数,默认值是1(左右两侧各加载一个页面)
addOnPageChangeListener
设置页面改变监听器,参数为OnPageChangeListener接口
OnPageChangeListener实现三个方法onPageScrolled、onPageSelected、onPageScrollStateChanged
setAdapter
设置适配器,参数:PagerAdapter、FragmentPagerAdapter和FragmentStatePagerAdapter类型
PagerAdapter需要实现四个方法getCount、isViewFromObject、instantiateItem、destroyItem
FragmentPagerAdapter需要实现两个方法getItem、getCount以及带FragmentManager类型参数的构造函数
FragmentStatePagerAdapter和FragmentPagerAdapter基本相同
(*)FragmentStatePagerAdapter和FragmentPagerAdapter的区别:
在ViewPager滑动时,超出setOffscreenPageLimit设置范围的Fragment销毁和重建的时候FragmentStatePagerAdapter执行onDestroyView、onDestroy、onCreate、onCreateView四个方法、即完全销毁释放内存,而FragmentPagerAdapter只执行onDestroyView、onCreateView两个方法。所以FragmentStatePagerAdapter适合数量极大的情况,如图片浏览,而FragmentPagerAdapter适合用在主界面,数量少不需要常驻内存的情况。
引导界面、图片浏览案例
直接看代码
public class MyPagerAdapter extends PagerAdapter {
private Context mContext;
private List<View> mViewList;
private LayoutInflater mInflater;
public MyPagerAdapter(Context context, List<View> viewList) {
mContext = context;
mViewList = viewList;
mInflater=LayoutInflater.from(context);
}
@Override
public int getCount() {
return mViewList.size();
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object o) {
return view==o;
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
View view=mViewList.get(position);
container.addView(view);
return view;
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
container.removeView(mViewList.get(position));
}
}
public class MainActivity extends AppCompatActivity {
public static final int INIT_POSTION = 0;
private ViewPager mViewPager;
private LinearLayout mDotLinearLayout;
private int[] mLayoutIds={
R.layout.first_layout,
R.layout.second_layout,
R.layout.third_layout
};
private int[] mImageViewIds={
R.mipmap.page1,
R.mipmap.page2,
R.mipmap.page3,
R.mipmap.page4
};
private List<View> mViews;
private List<ImageView> mDotViews;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化控件
initViews();
//初始化数据
initDatas();
MyPagerAdapter adapter=new MyPagerAdapter(this,mViews);
mViewPager.setAdapter(adapter);
mViewPager.setOffscreenPageLimit(2);
mViewPager.setCurrentItem(INIT_POSTION);
initDotViews(INIT_POSTION);
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int i, float v, int i1) {
}
@Override
public void onPageSelected(int i) {
initDotViews(i);
}
@Override
public void onPageScrollStateChanged(int i) {
}
});
}
private void initDatas() {
mViews = new ArrayList<>();
mDotViews=new ArrayList<>();
for (int i = 0; i < mImageViewIds.length; i++) {
//for (int i = 0; i < mLayoutIds.length; i++) {
//使用布局
/*View view=getLayoutInflater().inflate(mLayoutIds[i],null);
mViews.add(view);*/
//使用图片
ImageView imageView=new ImageView(this);
imageView.setImageResource(mImageViewIds[i]);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
mViews.add(imageView);
//导航
ImageView dot=new ImageView(this);
dot.setImageResource(R.mipmap.normal);
//设置布局参数
LinearLayout.LayoutParams layoutParams=new LinearLayout.LayoutParams(24,24);
layoutParams.leftMargin=20;
layoutParams.rightMargin=20;
dot.setLayoutParams(layoutParams);
dot.setEnabled(false);
mDotLinearLayout.addView(dot);
mDotViews.add(dot);
}
}
private void initDotViews(int i) {
for (int index = 0; index < mDotViews.size(); index++) {
mDotViews.get(index).setImageResource(index==i? R.mipmap.selected:R.mipmap.normal);
}
}
private void initViews() {
mViewPager = findViewById(R.id.view_pager);
mDotLinearLayout=findViewById(R.id.dot_layout);
}
}
Fragment与Tab标签结合案例
package com.imooc.administrator.tabviewpagerdemo;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class TestFragment extends Fragment {
public static final String TITLE = "title";
public static TestFragment getsInstance(String title){
TestFragment fragment=new TestFragment();
Bundle bundle=new Bundle();
bundle.putString(TITLE,title);
fragment.setArguments(bundle);
return fragment;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.fragment_test,container,false);
if(getArguments()!=null){
TextView textView = view.findViewById(R.id.test_tv);
String str=getArguments().getString(TITLE);
textView.setText(str);
}
return view;
}
@Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
}
}
package com.imooc.administrator.tabviewpagerdemo;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.TabHost;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity implements TabHost.TabContentFactory {
private ViewPager mViewPager;
private TabHost mTabHost;
private Fragment[] mFragments;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化控件
initViews();
//初始化数据
initDatas();
//添加监听器
addListeners();
}
private void initDatas() {
mFragments = new Fragment[]{
TestFragment.getsInstance("home"),
TestFragment.getsInstance("message"),
TestFragment.getsInstance("me")
};
//初始化主菜单
int[] titleIDs={
R.string.home,
R.string.message,
R.string.me
};
int[] drawableIDs={
R.drawable.main_tab_icon_home,
R.drawable.main_tab_icon_message,
R.drawable.main_tab_icon_me
};
for (int i = 0; i < titleIDs.length; i++) {
View view=getLayoutInflater().inflate(R.layout.main_tab_layout,null,false);
ImageView ivIcon=view.findViewById(R.id.main_tab_icon);
TextView tvTitle=view.findViewById(R.id.main_tab_txt);
View tab=view.findViewById(R.id.tab_bg);
ivIcon.setImageResource(drawableIDs[i]);
tvTitle.setText(titleIDs[i]);
tab.setBackgroundColor(getResources().getColor(R.color.white));
mTabHost.addTab(
mTabHost.newTabSpec(getString(titleIDs[i]))
.setIndicator(view)
.setContent(this)
);
}
mViewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {
@Override
public Fragment getItem(int i) {
return mFragments[i];
}
@Override
public int getCount() {
return mFragments.length;
}
});
}
private void initViews() {
mViewPager = findViewById(R.id.view_pager);
mTabHost = findViewById(R.id.tab_host);
mTabHost.setup();
}
private void addListeners() {
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int i, float v, int i1) {
}
@Override
public void onPageSelected(int i) {
if(mTabHost!=null){
mTabHost.setCurrentTab(i);
}
}
@Override
public void onPageScrollStateChanged(int i) {
}
});
mTabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() {
@Override
public void onTabChanged(String s) {
if(mTabHost!=null){
int position=mTabHost.getCurrentTab();
mViewPager.setCurrentItem(position);
}
}
});
}
@Override
public View createTabContent(String s) {
View view=new View(this);
view.setMinimumHeight(0);
view.setMinimumWidth(0);
return view;
}
}
布局
<?xml version="1.0" encoding="utf-8"?>
<TabHost
android:id="@+id/tab_host"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@id/line1"></android.support.v4.view.ViewPager>
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/line1"
android:visibility="gone"></FrameLayout>
<View
android:id="@+id/line1"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#dcdcdc"
android:layout_above="@android:id/tabs"/>
<TabWidget
android:id="@android:id/tabs"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_alignParentBottom="true"
android:showDividers="none"></TabWidget>
</RelativeLayout>
</TabHost>
布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tab_bg"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center">
<ImageView
android:id="@+id/main_tab_icon"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginTop="4dp"
android:src="@mipmap/ic_launcher"/>
<TextView
android:id="@+id/main_tab_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/color_main_tab_txt"
android:text="@string/app_name"/>
</LinearLayout>
<ImageView
android:id="@+id/red_dot_iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"/>
</RelativeLayout>
选择器,默认图片放在最后否则无效
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/tabbar_home_pressed"/>
<item android:state_selected="true" android:drawable="@drawable/tabbar_home_pressed"/>
<item android:drawable="@drawable/tabbar_home"/>
</selector>
二、屏幕适配
概念
屏幕尺寸:屏幕对角线长度,单位是英寸,1英寸=2.54厘米。
屏幕分辨率:在横纵向上的像素点数,单位是px,1px=1个像素点,一般以纵向像素*横向像素,如:1960*1080。
屏幕像素密度:每英寸上的像素点数、单位是dpi、即“dot per inch”的缩写。屏幕像素密度与屏幕尺寸和屏幕分辨率有关。计算方法,利用勾股定理计算出对角线像素点数,然后除以屏幕尺寸。
像素单位:
-px:pixel的缩写,像素,1px代表屏幕上一个物理的像素点
-dip、dp:都是Density Independent Pixels的缩写,即密度无关像素
-sp:scaled pixels,与dp类似,用于设置字体大小
在屏幕像素密度为160dpi的情况下,1dp=1px。假如320dpi→1dp=2px
换算公式:pxValue=(像素密度/160dpi)*dpValue
dp的范围划分
名称 像素密度范围
mdpi 120dpi-160dpi 中密度 1dp=1px
hdpi 160dpi-240dpi 高密度 1dp=1.5px
xhdpi 240dpi-320dpi 超高密度 1dp=2px
xxhdpi 320dpi-480dpi 超超高密度 1dp=3px
xxxhdpi 480dpi-640dpi 最高密度 1dp=4px
举例说明
华为畅享5S屏幕的分辨率为1280*720,尺寸是5.0英寸,屏幕像素密度值约为294,属于超高密度屏(xhdpi),那么它的1dp=2px。
如何适配
一、布局适配
1、禁用绝对布局
2、少用px
3、使用wrap_content、match_parent、layout_weight
1).wrap_content与layout_weight组合使用:先按照内容的多少去设定控件大小,然后按照权重的比例来分配剩余空间2).match_parent与layout_weight组合使用:控件大小=父容器大小+权重比例*剩余空间大小
例:
红textview:layout_width=“match_parent” layout_weight=1
蓝textview:layout_width=“match_parent” layout_weight=1
红色宽度=1match_parent+1/(1+2)*(1match_parent-2match_parent)=[1+1/3*(-1)]match_parent=2/3match_parent
蓝色宽度=1match_parent+2/(1+2)*(1match_parent-2match_parent)=[1+2/3*(-1)]match_parent=1/3match_parent
3).0dp与layout_weight组合使用:直接按照设定的比例分配空间
4、重建布局文件
二、图片适配
1、提供不同分辨率的备用位图
2、使用自动拉伸图
.9图片编辑
创建:图片上右键-》create 9-patch file-》路径,ok
编辑:图片左、上空白区域鼠标拖拽,选择拉伸区域;图片右、下空白区域鼠标拖拽,选择编辑区域。
三、百度地图
百度地图简介
功能:搜索、POI检索、定位、导航
官网:http://lbsyun.baidu.com