不超100行代码,实现Android上拉停靠
osag6609
8年前
<p>不超过100行代码的实现,先上图~</p> <p><strong>效果图</strong></p> <p style="text-align:center"><img src="https://simg.open-open.com/show/a06e47b39315fabfafc79dbdbbf59dca.gif"></p> <p style="text-align:center">简单的效果图</p> <p><strong>MyAdapter</strong></p> <p>由效果图分析可知,我们需要一个ListView,所以这里先贴出MyAdapter的代码,由于主题是实现上拉停靠效果,这里就不对MyAdapter进行优化了。</p> <pre> <code class="language-java">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; } }</code></pre> <p><strong>思路分析</strong></p> <ol> <li>ListView有两个头布局,分别为粉色块和褐色块</li> <li>ListView有个监听器OnScrollListener,在这个监听器中有onScroll方法可以获取当前第一个显示的view的position(即方法的参数firstVisibleItem)<br> public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)</li> <li>滑动逻辑,但firstVisibleItem为1时,此时褐色块已经滑出屏幕,屏幕只有粉色块和ListView,此时再往上滑粉色块不动,实现这种逻辑的方法有两个,我们可以通过监听手势来判断是否是否移动粉色块,这种方式稍微复杂。而这里我选择的是 在activity_main.xml布局中添加一个Visibility为gone的粉色块 , 每当粉色块的头布局要停靠时我们就显示activity_main.xml布局中的粉色块 ,事实上,粉色块的头布局并没有停靠,但是我们用activity_main.xml布局的粉色块就从视觉上起到了这样的作用!!!</li> <li>接下来贴出剩下的代码,并在注释中写出我遇到的坑=。=</li> </ol> <p><strong>head1.xml</strong></p> <pre> <code class="language-java"><?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></code></pre> <p><strong>head2.xml</strong></p> <pre> <code class="language-java"><?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></code></pre> <h3><strong>activity_main.xml</strong></h3> <pre> <code class="language-java"><?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></code></pre> <p><strong>MainActivity.java</strong></p> <pre> <code class="language-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); } } }</code></pre> <p> </p> <p> </p> <p>来自:http://www.jianshu.com/p/c37b16a6157d</p> <p> </p>