先看效果图
怕说不清楚,特来一张图 手绘
好 现在来说说效果实现中遇到的问题
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