如何在安卓系统中制作Instagram列表视图?

3
我想制作一个像Instagram一样的列表视图(分区式)。
我在谷歌上搜索了一些示例,但那些示例并不能很好地满足我的需求。这是我搜索到的链接:链接1链接2。然而,在第一个链接中,我无法找到任何关于类似Instagram的列表视图的解决方案。
至于第二个链接,我制作了一个演示,并且它可以完美地运行。唯一的问题是当我将两个TextView放入头部时,它就不再工作。
如果你能帮助我解决这个问题,那对我来说将会非常棒。
以下是来自第二个链接的演示:
package com.example.Section_Listview;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class InstaHeaderActivity 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); 
    }

    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();
            }
        }
    }

    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;
        }
    }



    public static class ViewHolder
    {
        TextView header;
        int previousTop = 0;
    }
}

main.xml

<?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>

child_header.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" >

    <TextView
        android:id="@+id/childHeader"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="2dp"
        android:text="childTest" />

</LinearLayout>

row.xml

<?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">

    <ListView
        android:id="@+id/childList"
        android:layout_width="fill_parent"
        android:layout_height="150dp"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/header"
        android:layout_marginTop="16dp" >
    </ListView>


    <TextView
        android:id="@+id/header"
        android:layout_width="fill_parent"
        android:layout_height="40dp"
        android:padding="12dp"
        android:text="Deneme Row"
        android:textColor="#ffffff" 
        android:background="#000000"/>

</RelativeLayout>
1个回答

3
首先,一个文件中不能有两个公共类,所以请移动。
public class ViewHolder {
    TextView header;
    int previousTop = 0;
}

将其写入单独的文件。如果可以的话,移除static修饰符,它不被允许。
要在标题行中显示第二个TextView,您必须在row.xml中声明它:
<?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:background="#FFFFFF"
    android:orientation="vertical" >

    <ListView
        android:id="@+id/childList"
        android:layout_width="fill_parent"
        android:layout_height="150dp"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/header"
        android:layout_marginTop="16dp" >
    </ListView>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="horizontal" >

        <TextView
            android:id="@+id/header"
            android:layout_width="wrap_content"
            android:layout_height="40dp"
            android:background="#000000"
            android:padding="12dp"
            android:textColor="#ffffff" />

        <TextView
            android:id="@+id/header2"
            android:layout_width="fill_parent"
            android:layout_height="40dp"
            android:background="#000000"
            android:padding="12dp"
            android:text="second textview"
            android:textColor="#ffffff" />
    </LinearLayout>
</RelativeLayout>

这个修改过的 row.xml 会让你得到以下的布局: enter image description here 要设置第二个 TextView 的内容,请将 ViewHolder 类更改为:
public class ViewHolder {
    TextView header;
    TextView header2;
    int previousTop = 0;
}

并且在您的活动中更改getView方法:

    @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);
            holder.header2 = (TextView) convertView.findViewById(R.id.header2);
            convertView.setTag(holder);
        }
        ViewHolder holder = (ViewHolder) convertView.getTag();
        holder.header.setText(getItem(position));
        holder.header2.setText("whatever you want");
        return convertView;
    }

第二个TextView被显示出来了,但我无法使用这段代码更改它的值。如果我设置第二个TextView的文本,则问题在于经过3或4行后,标题本身会隐藏。 - Mehul Ranpara
你可以通过相同的方式更改第一个TextView的内容来完成这个操作:((TextView) convertView.findViewById(R.id.header)).setText("所需文本"); - Mirco Widmer
是的,我也是这样做的。但是当我运行这个演示时,第三或第四个视图在滚动后就会隐藏起来。 - Mehul Ranpara
我不确定你在评论中的意思。我已经将工作项目上传到这里供您查看:https://www.dropbox.com/s/ttuoq4ehdi90dkt/InstagramClone.zip - Mirco Widmer
让我们在聊天中继续这个讨论:http://chat.stackoverflow.com/rooms/35516/discussion-between-mirco-widmer-and-mehul-ranpara - Mirco Widmer
@micro.widmer 上面的 ZIP 文件链接无法使用。您能再次上传吗? - Ashok Kateshiya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接