如何在android中實現自定義部分或ListView類似Instagram應用程序的標題。Android Listview自定義部分標題
http://prsarahevans.com/wp-content/uploads/2011/06/photo.PNG
當滾動起來有userpic,名稱和時間依然存在,當其他標題欄中去接近它,然後像動畫推它了吧。
謝謝。
如何在android中實現自定義部分或ListView類似Instagram應用程序的標題。Android Listview自定義部分標題
http://prsarahevans.com/wp-content/uploads/2011/06/photo.PNG
當滾動起來有userpic,名稱和時間依然存在,當其他標題欄中去接近它,然後像動畫推它了吧。
謝謝。
我能夠通過在列表視圖上使用滾動監聽器來解決此問題。 (在2.1測試)
讓我們說每個列表行我有一個像下面的佈局。有一個內容部分和一個頭部分。使用什麼視圖類型來標題或內容並不重要。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" android:background="#FFFFFF">
<ImageView
android:id="@+id/content"
android:layout_width="fill_parent"
android:layout_height="300dp"
android:scaleType="centerCrop"
android:src="@drawable/pic"
android:background="#aaaaff"
android:layout_marginTop="40dp"/>
<TextView
android:id="@+id/header"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:padding="12dp"
android:text="Deneme Row"
android:textColor="#000000"
android:background="#99ffffff"/>
</RelativeLayout>
測試佈局爲活性是如下面的:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView
android:id="@+id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</ListView>
</LinearLayout>
最後該活動的代碼如下所示。在這裏,我必須有一個使用ViewHolder存儲標題視圖的適配器,並且還需要一個變量來跟蹤每個連續滾動事件(previousTop)的滾動更改。這是因爲offsetTopAndBottom()更改與之前位置相關的視圖的偏移量。
public class TestActivity extends Activity implements AbsListView.OnScrollListener{
ListView list;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
list = (ListView) findViewById(R.id.list);
list.setAdapter(new Adapter(this));
list.setOnScrollListener(this);
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
//the listview has only few children (of course according to the height of each child) who are visible
for(int i=0; i < list.getChildCount(); i++){
View child = list.getChildAt(i);
ViewHolder holder = (ViewHolder) child.getTag();
//if the view is the first item at the top we will do some processing
if(i == 0){
boolean isAtBottom = child.getHeight() <= holder.header.getBottom();
int offset = holder.previousTop - child.getTop();
if(!(isAtBottom && offset > 0)){
holder.previousTop = child.getTop();
holder.header.offsetTopAndBottom(offset);
holder.header.invalidate();
}
} //if the view is not the first item it "may" need some correction because of view re-use
else if (holder.header.getTop() != 0) {
int offset = -1 * holder.header.getTop();
holder.header.offsetTopAndBottom(offset);
holder.previousTop = 0;
holder.header.invalidate();
}
}
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {}
private static class Adapter extends ArrayAdapter<String> {
public Adapter(Context context) {
super(context, R.layout.row, R.id.header);
for(int i=0; i < 50; i++){
add(Integer.toString(i));
}
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
convertView = LayoutInflater.from(getContext()).inflate(R.layout.row, parent, false);
ViewHolder holder = new ViewHolder();
holder.header = (TextView) convertView.findViewById(R.id.header);
convertView.setTag(holder);
}
ViewHolder holder = (ViewHolder) convertView.getTag();
holder.header.setText(getItem(position));
return convertView;
}
}
private static class ViewHolder {
TextView header;
int previousTop = 0;
}
}
如果您正在使用列表視圖,那麼您的列表項目中有2個視圖。一個是標題,另一個實際上是項目。
隱藏標題視圖最初和作爲滾動狀態更改或用戶觸摸您的列表項更改標題的可見性。
在你的setcontentview做了如下面的代碼之後。
ListView list = getListView();
View footer = getLayoutInflater().inflate(R.layout.footerlayout, list, false);
View header = getLayoutInflater().inflate(R.layout.headerlayout, list, false);
list.addHeaderView(header);
list.addFooterView(footer);
我已經改善Siyamed的問題一點點,這樣,當如果在列表視圖項的位圖改變視圖重繪例如頭部並沒有消失。
不是使用相對於最後位置的座標,而是使用相對於視圖頂部的座標,並使用填充而不是偏移。
@Override
public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
for(int i=0; i < list.getChildCount(); i++){
View child = list.getChildAt(i);
ViewHolder holder = (ViewHolder) child.getTag();
if(i == 0){
try {
boolean isAtBottom = child.getHeight() <= holder.movingHeader.getBottom();
if(!(isAtBottom)){
if (child.getTop() >= 0){}
else if (child.getHeight() - movingHeader.getHeight() - 1 > -child.getTop())
{
holder.movingHeader.setPadding(0, -child.getTop(), 0, 0);
holder.movingHeader.invalidate();
}
else {
holder.movingHeader.setPadding(0, child.getHeight() - movingHeader.getHeight(), 0, 0);
holder.movingHeader.invalidate();
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
else if (holder.movingHeader.getPaddingTop() != 0)
{
holder.movingHeader.setPadding(0, 0, 0, 0);
holder.movingHeader.invalidate();
}
}
}
我知道這個問題是有點老了,但設法找到StickyListHeaders庫,它確實提取了部分頭創造了很好的工作。
嘿siyamed, 這是非常有用的。 在我的情況下,我在ListView(Parent)中還有一個ListView(child)。所以當我向下滾動時頭部不能正常工作...... – ashish2py 2012-04-26 12:19:48
如果在child-listview中沒有數據,那麼它可以正常工作.. >示例應用程序 https://bitbucket.org/ashish2py/instagramheader – ashish2py 2012-04-26 12:34:10
我會試試看。謝謝! – 2012-04-27 13:30:48