您的位置:首页 > 其它

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

2015-12-11 16:53 232 查看
/article/2336606.html

先看效果图



怕说不清楚,特来一张图 手绘



好 现在来说说效果实现中遇到的问题

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: