如何在GridView的最后一项之后添加页脚ProgressBar

时间:2012-08-14 09:02:34

标签: android android-layout gridview

这是我的代码。它在数据不足时加载更多数据。我想在加载更多数据时将页脚ProgressBar添加到GridView 。怎么做?我在StackOverflow上看过很多问题,但没有答案。

public class MainActivity extends Activity {
    private static final String TAG = "MainActivity";
    private final List<Integer> commonImageList = new ArrayList<Integer>();
    private int index = 0;
    private boolean isLoading = false;
    private static final int NUM = 18;
    private ImageAdapter adapter;

    @Override
    public void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final Task task = new Task(mThumbIds, index);
        task.setOnPostExecuteListener(new OnPostExecuteListener<List<Integer>>() {
            @Override
            public void onPostExecute(final List<Integer> result) {
                System.out.println("RESULT: " + result);
                if(result.isEmpty()) {
                    return;
                }

                // Store it.
                commonImageList.addAll(result);

                // Prepare gridView.
                final GridView gridview = (GridView) findViewById(R.id.gridview);
                adapter = new ImageAdapter(MainActivity.this, commonImageList);
                gridview.setAdapter(adapter);

                gridview.setOnScrollListener(new OnScrollListener() {
                    @Override
                    public void onScrollStateChanged(final AbsListView view, final int scrollState) {

                    }

                    @Override
                    public void onScroll(final AbsListView view, final int firstVisibleItem,
                            final int visibleItemCount, final int totalItemCount) {
                        System.out.println("firstVisibleItem: " + firstVisibleItem);
                        System.out.println("visibleItemCount: " + visibleItemCount);
                        System.out.println("totalItemCount: " + totalItemCount);

                        final boolean loadMore = (firstVisibleItem + visibleItemCount >= totalItemCount);
                        System.out.println("loadMore: " + loadMore);
                        System.out.println("isLoading: " + isLoading);

                        if(loadMore && !isLoading) {
                            // TODO Show footer here.


                            ShowLog.showLogInfo(TAG, "============= LOAD MORE =============");
                            // Get more images.
                            index = index + NUM;
                            final Task task = new Task(mThumbIds, index);
                            task.setOnPreExecuteListener(new OnPreExecuteListener() {
                                @Override
                                public void onPreExecute() {
                                    isLoading = true;
                                }
                            });
                            task.setOnPostExecuteListener(new OnPostExecuteListener<List<Integer>>() {
                                @Override
                                public void onPostExecute(final List<Integer> result) {
                                    System.out.println("RESULT222: " + result);

                                    if(result.isEmpty()) {
                                        return;
                                    }
                                    System.out.println("HIEU THONG MINH");

                                    // Update common list.
                                    commonImageList.addAll(result);

                                    // Update adapter.
                                    adapter.notifyDataSetChanged();

                                    isLoading = false;
                                }
                            });
                            task.execute();
                        }
                    }
                });
            }
        });
        task.execute();

    }

    private class Task extends AbstractWorkerTask<Void, Void, List<Integer>> {
        private final Integer []thumbs;
        private final int index;

        public Task(final Integer []thumbs, final int index) {
            this.thumbs = thumbs;
            this.index = index;
        }

        @Override
        protected List<Integer> doInBackground(final Void... params) {
            final List<Integer> list = new ArrayList<Integer>();
            for(int i = index; i < index + NUM && i < thumbs.length; ++i) {
                list.add(thumbs[i]);
            }
            return list;
        }
    }

    public static class ImageAdapter extends BaseAdapter {
        private final Context context;              
        private final List<Integer> imageList;

        public ImageAdapter(final Context c, final List<Integer> imageList) {
            context = c;
            this.imageList = imageList;
        }

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

        @Override
        public Object getItem(final int position) {
            return null;
        }

        @Override
        public long getItemId(final int position) {
            return 0;
        }

        // create a new ImageView for each item referenced by the Adapter
        @Override
        public View getView(final int position, final View convertView, final ViewGroup parent) {
            ImageView imageView;
            if (convertView == null) {  // if it's not recycled, initialize some attributes
                imageView = new ImageView(context);
                imageView.setLayoutParams(new GridView.LayoutParams(150, 150));
                imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
                imageView.setPadding(8, 8, 8, 8);

            } else {
                imageView = (ImageView) convertView;
            }

            imageView.setImageResource(imageList.get(position));
            return imageView;
        }
    }

    // references to our images
    private static final Integer[] mThumbIds = {
            R.drawable.sample_2, R.drawable.sample_3,
            R.drawable.sample_4, R.drawable.sample_5,
            R.drawable.sample_6, R.drawable.sample_7,
            R.drawable.sample_0, R.drawable.sample_1,
            R.drawable.sample_2, R.drawable.sample_3,
            R.drawable.sample_4, R.drawable.sample_5,
            R.drawable.sample_6, R.drawable.sample_7,
            R.drawable.sample_0, R.drawable.sample_1,
            R.drawable.sample_2, R.drawable.sample_3,
            R.drawable.sample_4, R.drawable.sample_5,
            R.drawable.sample_6, R.drawable.sample_7,
            R.drawable.sample_0, R.drawable.sample_1,
            R.drawable.sample_2, R.drawable.sample_3,
            R.drawable.sample_4, R.drawable.sample_5,
            R.drawable.sample_6, R.drawable.sample_7,
            R.drawable.sample_0, R.drawable.sample_1,
            R.drawable.sample_2, R.drawable.sample_3,
            R.drawable.sample_4, R.drawable.sample_5,
    };
}

activity_main.xml中

<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/gridview"
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"
    android:columnWidth="150dp"
    android:numColumns="3"
    android:verticalSpacing="10dp"
    android:horizontalSpacing="10dp"
    android:stretchMode="columnWidth"
    android:gravity="center"
/>

2 个答案:

答案 0 :(得分:3)

这里我添加了GridView中加载更多项目的逻辑 的 1。在Adapter的最后输入数据

创建一个假项目
public class MediaGridAdapter extends BaseAdapter {

    private ArrayList<Media> list;
    private final Media special = new Media("-1", "", "", "", ""); 

    public MediaGridAdapter(Context context, int imageID, ArrayList<Media> array, int type) {

        list = array;

        if(list != null) {
            list.add(special);
        }
            }

public void appendDataList(ArrayList<Media> appendedList, boolean isEnd) { //called in postExecute to append new data

    //remove special element in original list
    list.remove(list.size() - 1);
    //append collection of media to list
    list.addAll(appendedList);
    //check to add special element
    if(!isEnd) {

        list.add(special);
    }
}   
}

<强> 2。在getView方法中:检查它是否是最后一个位置(是我们的假项目)为此返回特殊布局(进度条...)。

    if(position == (list.size() - 1)) {

        Context context = parent.getContext();
        item = (RelativeLayout) LayoutInflater.from(context).inflate(R.layout.item_special_more, null);
        item.setTag(MORE_BUTTON);
        return item;
    }

onItemClick检查标记中的最后一个标记,以启动getMoreAsyncTask

if (v.getTag().equals(MediaGridAdapter.MORE_BUTTON)) {    

                        GetMoreItems task = new GetMoreItems();
                        task.execute(url);
                        return;
                    }

答案 1 :(得分:0)

通过在制作项目可见/消失时利用动态布局更改,我发现了一种更少侵入性的方法。为此,我使用了相对布局,但也可以使用其他东西。 这是xml布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="vertical" android:layout_width="match_parent"
   android:layout_height="match_parent">

   <ProgressBar
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/loader_view"
    android:visibility="visible"
    android:layout_alignParentBottom="true"
    android:layout_alignParentStart="true"
    android:layout_centerHorizontal="true"
    android:padding="32dp" />

<GridView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/grid_view"
    android:layout_toStartOf="@id/loader_view"
    android:layout_alignParentRight="true"
    android:layout_alignParentEnd="false"
    android:layout_above="@+id/loader_view"
    android:numColumns="@integer/grid_view_column_count"
    android:scrollbarStyle="insideOverlay"
    android:scrollbars="none"
    android:listSelector="@null"
    android:smoothScrollbar="false"></GridView>

</RelativeLayout>

关于此的一些注释:

进度条显示在gridview下面,但您必须先在xml中定义它,因为GridView中有:android:layout_toStartOf="@id/loader_view"引用。

您可以增加进度条上的填充以使加载区域更大,例如与网格的行高匹配。

网格视图android:numColumns="@integer/grid_view_column_count"是来自资源的动态值,随时可以更改它。您可以在那里使用一个数字,但外部效果更好,因为您可以根据屏幕宽度设置值。

以下代码将转到Fragment的onCreateView:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.grid_and_loader_view, container, false);
    GridView gridView = (GridView) view.findViewById(R.id.grid_view);
    //store a class reference to the loader:
    _loader = (ProgressBar) view.findViewById(R.id.loader_view);
    //set up your grid adapter e.g.:
    //_adapter = new GridImageAdapter(this.getActivity());
    //gridView.setAdapter(_adapter);
    return view;
}

您可以通过以下方式开始/停止片段加载:

public void startLoading() {
    if(_loader != null) {
        _loader.setVisibility(View.VISIBLE);
    }
}

public void stopLoading() {
    if(_loader != null) {
        _loader.setVisibility(View.GONE);
    }
}

我发现,更好的解决方案是控制适配器的加载行为, 所以我将片段作为可加载接口(可选)形式的参考传递给适配器,并从那里调用上面的start / stopLoading函数。