Android网络操作与数据存储(四):实战开发

目录

一、ViewPager实现导航效果

应用场景:

应用背景

概念介绍

ViewPager常用方法

setCurrentItem

setOffscreenPageLimit

addOnPageChangeListener

setAdapter

引导界面、图片浏览案例

 

Fragment与Tab标签结合案例

二、屏幕适配

概念

如何适配

一、布局适配

1、禁用绝对布局

2、少用px

3、使用wrap_content、match_parent、layout_weight

4、重建布局文件

二、图片适配

1、提供不同分辨率的备用位图

2、使用自动拉伸图

三、百度地图

百度地图简介

创建应用及SDK下载

SDK文件夹结构分析

核心类库以及功能实现

功能总结

四、案例:仿外卖开发点餐App

五、面试精讲:ContentProvider


一、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

创建应用及SDK下载

SDK文件夹结构分析

核心类库以及功能实现

功能总结

四、案例:仿外卖开发点餐App

五、面试精讲:ContentProvider

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值