Android上拉停靠简单实现

作者: iceIC | 来源:发表于2016-09-17 14:21 被阅读1281次

不超过100行代码的实现,先上图~

效果图

简单的效果图

MyAdapter

由效果图分析可知,我们需要一个ListView,所以这里先贴出MyAdapter的代码,由于主题是实现上拉停靠效果,这里就不对MyAdapter进行优化了。

public class MyAdapter extends BaseAdapter{    

    private List<String> mData;    

    public MyAdapter(List<String> data) {
        mData = data;    
    }    

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

    @Override    
    public Object getItem(int position) 
    {        
        return null;    
    }   
 
    @Override    
    public long getItemId(int position) 
    {        
        return 0;    
    }   
 
    @Override    
    public View getView(int position, View convertView, ViewGroup parent) {
        View view=LayoutInflater.from(parent.getContext())
                .inflate(android.R.layout.simple_list_item_1, parent, false);
        ((TextView) view.findViewById(android.R.id.text1)).setText(mData.get(position));                  
        return view;    
    }
}

思路分析

  1. ListView有两个头布局,分别为粉色块和褐色块
  2. ListView有个监听器OnScrollListener,在这个监听器中有onScroll方法可以获取当前第一个显示的view的position(即方法的参数firstVisibleItem)
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
  3. 滑动逻辑,但firstVisibleItem为1时,此时褐色块已经滑出屏幕,屏幕只有粉色块和ListView,此时再往上滑粉色块不动,实现这种逻辑的方法有两个,我们可以通过监听手势来判断是否移动粉色块,这种方式稍微复杂。而这里我选择的是在activity_main.xml布局中添加一个Visibility为gone的粉色块每当粉色块的头布局要停靠时我们就显示activity_main.xml布局中的粉色块,事实上,粉色块的头布局并没有停靠,但是我们用activity_main.xml布局的粉色块就从视觉上起到了这样的作用!!!
  4. 接下来贴出剩下的代码,并在注释中写出我遇到的坑=。=

head1.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"   
android:layout_width="match_parent"    
android:layout_height="match_parent"    
android:orientation="vertical">    
        <LinearLayout
        //坑1: ListView的头布局(ViewGroup)必须有个View或ViewGroup        
        android:layout_width="match_parent"
        //褐色块高度100dp 粉色块高度50dp 只是用于区分而已        
        android:layout_height="100dp"
        //褐色       
        android:background="#c2461d" />
</LinearLayout>

head2.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
xmlns:android="http://schemas.android.com/apk/res/android"    
android:orientation="vertical" android:layout_width="match_parent"    
android:layout_height="match_parent">    
        <LinearLayout   
        android:layout_width="match_parent"        
        android:layout_height="50dp"
        //粉色
        android:background="#FF4081"        
        android:orientation="vertical">    
        </LinearLayout>
</LinearLayout>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
//坑2: 这里用FrameLayout并将粉色块定义在ListView的后面,
//      这样显示粉色块时会盖在ListView的粉色块头布局上。
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"    
android:layout_width="match_parent"    
android:layout_height="match_parent"    
android:orientation="vertical">    
        <ListView        
        android:id="@+id/lv"        
        android:layout_width="match_parent"        
        android:layout_height="match_parent"/>   
 
        <LinearLayout        
        android:id="@+id/tab" 
        //这里一开始要设置为gone,在代码中需要停靠时显示       
        android:visibility="gone"        
        android:layout_width="match_parent"        
        android:layout_height="50dp"
        //粉色块 用于实现视觉上是停靠的~        
        android:background="#FF4081"        
        android:orientation="vertical"/>
</FrameLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity 
                        implements AbsListView.OnScrollListener {    
        private View tab;    
        @Override    
        protected void onCreate(Bundle savedInstanceState) {        
                super.onCreate(savedInstanceState);        
                setContentView(R.layout.activity_main);
                //开始创建假数据   
                List<String> list = new ArrayList<>();        
                for (int i = 0; i < 200; i++) {            
                        list.add(i + "");
                    }
                //假数据创建完毕
//-------------------华丽分隔线----------------------------        
                ListView listView = (ListView) findViewById(R.id.lv);        
                listView.setAdapter(new MyAdapter(list));        
                LayoutInflater inflater = LayoutInflater.from(this);        
                View view1 = inflater.inflate(R.layout.head1, null);        
                View view2 = inflater.inflate(R.layout.head2, null);        
                tab = findViewById(R.id.tab);        
                listView.addHeaderView(view1);        
                listView.addHeaderView(view2);        
                listView.setOnScrollListener(this);    
        }    
                

        @Override    
        public void onScrollStateChanged(AbsListView view, int scrollState) {
        //没用的方法 pass
        }  
  
        @Override    
        public void onScroll(AbsListView view, int firstVisibleItem, 
                                int visibleItemCount, int totalItemCount) {        
                if (firstVisibleItem == 1) 
                {       
                        //褐色块移除屏幕时,粉色块进行'停靠'     
                        tab.setVisibility(View.VISIBLE);        
                }        
                if (firstVisibleItem == 0) {        
                        //褐色块移入屏幕时,粉色块取消'停靠'
                        //此时必须得gone掉,不然看起来还是停靠在上面
                        tab.setVisibility(View.GONE);        
                }    
        }
}

结语

代码已上传github:https://github.com/ice45571/Docked

相关文章

网友评论

    本文标题:Android上拉停靠简单实现

    本文链接:https://www.haomeiwen.com/subject/zuxwettx.html