Scrollview中嵌套ViewPager中嵌套ListView 滑动中tab固定顶部ScrollingTricks效果特效

先看效果图
这里写图片描述

怕说不清楚,特来一张图 手绘
这里写图片描述

好 现在来说说效果实现中遇到的问题
1:scrollview中嵌套viewpager中嵌套listview
出现了 listview不显示 因为在scrollview中所以要重新计算listview每个子View的高度然后要将整个高度设置为viewpager的高度
给viewpager这是必须的,不然同样也显示不了listview的内容

2:我listview显示出来了 尼玛上下滑动失效
这里真是大坑,差点爬不起来,因为我开始是这样
看起来是没有问题的

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ListView
        android:id="@+id/lv_data"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</RelativeLayout>

用的是LinearLayout listview不滚动,我换成RelativeLayout竟然好了

这真是卧槽了 我真不知道咋回事

3:还有就是tab的顶部固定显示 貌似叫做ScrollingTricks效果
这个我开始像用一个布局一直放在顶部,然后根据我滑动的位置来显示与否,我是这么想啦,但是习惯性的查了一下,然后发现一个方法
view.setTranslationY(scroolY)
这个好像可以将一个控件设置到指定位置 那个Demo里面有写 我就按照写法来实现了
主要是获取scrollview滚动中的位置来设置需要显示到指定位置的控件的位置

Demo结构图
这里写图片描述

首页布局 里面的FrameLayout必须

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.example.daemon1993.myapplication.MyScrollView
        android:id="@+id/mysl"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical">

                <TextView
                    android:id="@+id/tv_show"
                    android:layout_width="match_parent"
                    android:layout_height="150dp"
                    android:text="@string/hello_world" />

                <android.support.v4.view.ViewPager
                    android:id="@+id/vp"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content" />

            </LinearLayout>

            <TextView
                android:id="@+id/tv_db"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:text="顶部" />

        </FrameLayout>

    </com.example.daemon1993.myapplication.MyScrollView>


    <ImageView
        android:id="@+id/in_go2top"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_marginBottom="5dp"
        android:layout_marginRight="5dp"
        android:src="@mipmap/ic_launcher"
        android:visibility="gone" />


</RelativeLayout>

Fragment布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
     >

    <ListView
        android:id="@+id/lv_data"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

</RelativeLayout>

MainActivity

package com.example.daemon1993.myapplication;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import com.snappydb.DB;
import com.snappydb.DBFactory;
import com.snappydb.SnappydbException;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Protocol;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.ResponseBody;

import java.io.IOException;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {


    public ViewPager vp;
    TextView tvshow;

    public MyScrollView mysl;
    ImageView ingo2top;

    private ArrayList<Fragment> list;
    private int kkk;
    private TextView tv_db;
    private int kkkk;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();

        list = new ArrayList<Fragment>();

        for (int i = 0; i < 2; i++) {
            list.add(new Fragment1());
        }

        MyPagerAdpater myPagerAdpater = new MyPagerAdpater(getSupportFragmentManager());

        vp.setAdapter(myPagerAdpater);

        mysl.setOnScrollListener(new MyScrollView.OnScrollListener() {
            @Override
            public void onScrollchanged(int scrollY) {

             //重点在这里
                Log.e("haha ", scrollY + "  " + vp.getTop());
                int translation = Math.max(scrollY, vp.getTop() - kkkk);
                tv_db.setTranslationY(translation);

                if (scrollY > kkk) {
                    ingo2top.setVisibility(View.VISIBLE);
                } else {
                    ingo2top.setVisibility(View.GONE);
                }
            }

            @Override
            public void onTouchUp() {
            }

            @Override
            public void onTouchDown() {
            }
        });

        //获取控件大小
        tvshow.post(new Runnable() {
            @Override
            public void run() {
                kkk = tvshow.getHeight();
                kkkk = tv_db.getHeight();
            }
        });

        ingo2top.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.e("haha", "hahaha");
                mysl.smoothScrollTo(0, 0);
            }
        });

        mysl.smoothScrollTo(0, 0);

        //这里没啥用  开始的一个Demo效果 实现缓存什么的   不用管
        final OkHttpClient client = new OkHttpClient();
        new Thread(new Runnable() {
            @Override
            public void run() {
                Request request = new Request.Builder().url("http://www.baidu.com").build();
                Response response = null;
                try {
                    response = client
                            .newCall(request).execute();
                    try {
                        DB snappydb = DBFactory.open(MainActivity.this, "okhttp");

                        //程序进入第一次联网 保存这个
                        Protocol protocol = response.protocol();
                        snappydb.put("response_protocol", protocol.toString());

                        snappydb.put("json", response.body().string());

                        String json = snappydb.get("json");

                        if (json == null) {
                            Log.e("haha", "缓存没有,存进去");

                        } else {
                            Log.e("haha", "缓存读取" + json);

                            //构建response
                            ResponseBody responseBody = ResponseBody.create(null, json);
                            Request request1 = new Request.Builder().url("http://www.eh2h.com").build();
                            Protocol protocol1 = Protocol.get(snappydb.get("response_protocol"));

                            Response response1 = new Response.Builder()
                                    .request(request1)
                                    .code(200)
                                    .protocol(protocol1)
                                    .body(responseBody)
                                    .build();

                            Log.e("response ", response1.body().string());
                        }


                    } catch (SnappydbException e) {
                        e.printStackTrace();
                    }


                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();




    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    private void initView() {
        tvshow = (TextView) findViewById(R.id.tv_show);
        tv_db = (TextView) findViewById(R.id.tv_db);
        vp = (ViewPager) findViewById(R.id.vp);
        mysl = (MyScrollView) findViewById(R.id.mysl);
        ingo2top = (ImageView) findViewById(R.id.in_go2top);
    }


    class MyPagerAdpater extends FragmentPagerAdapter {

        public MyPagerAdpater(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            return list.get(position);
        }

        @Override
        public int getCount() {
            return list.size();
        }
    }

}

Fragment

package com.example.daemon1993.myapplication;

import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Toast;

import java.util.ArrayList;

/**
 * Created by Daemon1993 on 15/8/22.
 */
public class Fragment1 extends Fragment {

    private ListView lvdata;
    private ArrayList<String> list;


    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view=inflater.inflate(R.layout.fragment1,null,false);
        lvdata = (ListView)view.findViewById(R.id.lv_data);
        list=new ArrayList<String>();
        for(int i=0 ; i<100 ; i++){
            list.add("123");
        }
        MyAdpater myAdpater=new MyAdpater(getActivity());

        lvdata.setAdapter(myAdpater);
        int listViewHeight = ViewUtil.setListViewHeightBasedOnChildren1(lvdata);

        ViewGroup.LayoutParams params = ((MainActivity)getActivity()).vp.getLayoutParams();
        params.height = listViewHeight;
        ((MainActivity)getActivity()).vp.setLayoutParams(params);


        return view;
    }


    class MyAdpater extends BaseAdapter {

        private  LayoutInflater layoutInflater;
        private Context context;

        public MyAdpater(Context context) {
            this.context=context;
            layoutInflater=LayoutInflater.from(context);

        }

        @Override
        public int getCount() {
            return list.size();
        }

        @Override
        public Object getItem(int position) {
            return list.get(position);
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if(convertView==null) {
                convertView = layoutInflater.inflate(R.layout.item_view,null,false);
            }else{

            }
            return convertView;
        }
    }
}

MyScrollView

package com.example.daemon1993.myapplication;

import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ScrollView;

/**
 * Created by Daemon1993 on 15/8/22.
 */
public class MyScrollView extends ScrollView {

    public OnScrollListener onScrollListener;

    public MyScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void setOnScrollListener(OnScrollListener onScrollListener) {
        this.onScrollListener = onScrollListener;
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (onScrollListener != null){
            onScrollListener.onScrollchanged(t);
        }
    }

    /**
     * 由垂直方向滚动条代表的所有垂直范围,缺省的范围是当前视图的画图高度。
     */
    public int computeVerticalScrollRange(){
        return super.computeVerticalScrollRange();
    }

    public interface OnScrollListener {
        public void onScrollchanged(int t);

        public void onTouchUp();

        public void onTouchDown();
    }
}

ViewUtils

public class ViewUtil {
    public static void setListViewHeightBasedOnChildren(ListView listView) {
        ListAdapter listAdapter = listView.getAdapter();
        if (listAdapter == null) {
            return;
        }

        int totalHeight = 0;
        for (int i = 0; i < listAdapter.getCount(); i++) {
            View listItem = listAdapter.getView(i, null, listView);
            listItem.measure(0, 0);
            totalHeight += listItem.getMeasuredHeight();
        }

        ViewGroup.LayoutParams params = listView.getLayoutParams();
        params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
        listView.setLayoutParams(params);
    }

    /**
     * 获取Listview的高度,然后设置ViewPager的高度
     * @param listView
     * @return
     */
    public static int setListViewHeightBasedOnChildren1(ListView listView) {
        //获取ListView对应的Adapter
        ListAdapter listAdapter = listView.getAdapter();
        if (listAdapter == null) {
            // pre-condition
            return 0;
        }

        int totalHeight = 0;
        for (int i = 0, len = listAdapter.getCount(); i < len; i++) { //listAdapter.getCount()返回数据项的数目
            View listItem = listAdapter.getView(i, null, listView);
            listItem.measure(0, 0); //计算子项View 的宽高
            totalHeight += listItem.getMeasuredHeight(); //统计所有子项的总高度
        }

        ViewGroup.LayoutParams params = listView.getLayoutParams();
        params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
        //listView.getDividerHeight()获取子项间分隔符占用的高度
        //params.height最后得到整个ListView完整显示需要的高度
        listView.setLayoutParams(params);
        return params.height;
    }

}

代码不够明确的话 直接下载demo吧
http://download.csdn.net/detail/liubo080852/9038509

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值