【问题标题】:android listview loadmore button with xml parsing带有xml解析的android listview loadmore按钮
【发布时间】:2012-10-19 11:17:32
【问题描述】:

您好,我必须在 Android 应用程序中使用 xml 解析开发带有加载更多按钮的列表视图。

这里我遇到了一些问题。

我的 xml 提要为空意味着如何在最后一页隐藏加载更多按钮。

我在这里使用了下面的代码。

public class CustomizedListView extends Activity {
// All static variables
private String URL = "http://dev.mmm.com/xctesting/xcart444pro/retrieve.php?page=1";
// XML node keys
static final String KEY_SONG = "Order"; 
    static final String KEY_TITLE = "orderid";
static final String KEY_DATE = "date";
static final String KEY_ARTIST = "payment_method";
    int current_page = 1;
ListView lv;
LazyAdapter adapter;
ProgressDialog pDialog; 

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    lv = (ListView) findViewById(R.id.list);

    ArrayList<HashMap<String, String>> songsList = new ArrayList<HashMap<String, String>>();

    XMLParser parser = new XMLParser();
    String xml = parser.getXmlFromUrl(URL); // getting XML from URL
    Document doc = parser.getDomElement(xml); // getting DOM element

    NodeList nl = doc.getElementsByTagName(KEY_SONG);
    // looping through all song nodes <song>
    for (int i = 0; i < nl.getLength(); i++) {
        // creating new HashMap
        HashMap<String, String> map = new HashMap<String, String>();
        Element e = (Element) nl.item(i);
        // adding each child node to HashMap key => value
        map.put(KEY_ID, parser.getValue(e, KEY_ID));
        map.put(KEY_TITLE, parser.getValue(e, KEY_TITLE));
        map.put(KEY_ARTIST, parser.getValue(e, KEY_ARTIST));
              songsList.add(map);
    }

    Button btnLoadMore = new Button(this);
    btnLoadMore.setText("Load More");

    btnLoadMore.setBackgroundResource(R.drawable.lgnbttn);
    // Adding Load More button to lisview at bottom
    lv.addFooterView(btnLoadMore);

    // Getting adapter
    adapter = new LazyAdapter(this, songsList);
    lv.setAdapter(adapter);
                btnLoadMore.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {
            // Starting a new async task
            new loadMoreListView().execute();
        }
    });
}
    private class loadMoreListView extends AsyncTask<Void, Void, Void> {

        @Override 
        protected void onPreExecute() {
            // Showing progress dialog before sending http request
            pDialog = new ProgressDialog(
                    CustomizedListView.this);
            pDialog.setMessage("Please wait..");
            //pDialog.setIndeterminateDrawable(getResources().getDrawable(R.drawable.my_progress_indeterminate));
            pDialog.setIndeterminate(true);
            pDialog.setCancelable(false);
            pDialog.show(); 

            pDialog.setContentView(R.layout.custom_dialog);


        }
        protected Void doInBackground(Void... unused) {

                    current_page += 1;

                    // Next page request
                    URL = "http://dev.mmm.com/xctesting/xcart444pro/retrieve.php?page=" + current_page;

                    ArrayList<HashMap<String, String>> songsList = new ArrayList<HashMap<String, String>>();

                    XMLParser parser = new XMLParser();
                    String xml = parser.getXmlFromUrl(URL); // getting XML from URL
                    Document doc = parser.getDomElement(xml); // getting DOM element

                    NodeList nl = doc.getElementsByTagName(KEY_SONG);


                    NodeList nl = doc.getElementsByTagName(KEY_SONG);
                    if (nl.getLength() == 0)
                      {
                          btnLoadMore.setVisibility(View.GONE);
                          pDialog.dismiss();

                      }
                      else

                    // looping through all item nodes <item>
                    for (int i = 0; i < nl.getLength(); i++) {
                        // creating new HashMap
                        HashMap<String, String> map = new HashMap<String, String>();
                        Element e = (Element) nl.item(i);

                        // adding each child node to HashMap key => value
                        map.put(KEY_ID, parser.getValue(e, KEY_ID));
                        map.put(KEY_TITLE, parser.getValue(e, KEY_TITLE));
                        map.put(KEY_ARTIST, parser.getValue(e, KEY_ARTIST));
                 songsList.add(map);
                    }

                    // get listview current position - used to maintain scroll position
                    int currentPosition = lv.getFirstVisiblePosition();

                    // Appending new data to menuItems ArrayList
                    adapter = new LazyAdapter(
                            CustomizedListView.this,
                            songsList);
                    lv.setAdapter(adapter);
             lv.setSelectionFromTop(currentPosition + 1, 0);


            }
            });

            return (null);
        }


        protected void onPostExecute(Void unused) {
            // closing progress dialog
            pDialog.dismiss();

        }
    }
}

编辑:

在这里我必须运行应用程序意味着列表视图显示在每页 4 个项目上。我的最后一页有 1 个项目。请参考这个截图:lastpage 在最后一页我必须点击加载更多按钮意味着必须进入下一个活动并成功隐藏空白页面上的按钮..请参考此截图:empty page-so hide the button

我必须检查空白页面的条件:

    if (nl.getLength() == 0)
                    {
                        btnLoadMore.setVisibility(View.GONE);
                        pDialog.dismiss();

                    }

最后一页的条件怎么写??????请帮帮我

这里我希望o/p隐藏最后一页的按钮

请帮助我。我如何检查条件。以编程方式给我一些代码。

【问题讨论】:

    标签: java android xml-parsing android-listview


    【解决方案1】:

    首先,你为什么在 AsyncTaks 中使用 runOnUiThread?这不应该是必要的。必须在后台运行的代码,在 doInBackground 方法中就足够了。

    此外,您可以使用 AsyncTask 的第三个参数类型将来自 te doInBackground 的结果返回到 onPostExecute。然后根据结果,您可以在此处更改按钮的可见性。

    为此,对 Button 的引用(在您的情况下为 btnLoadMore)应该是一个实例变量,因此它应该在类中定义,而不是在 onCreate 方法中。否则将无法从该方法外部访问。

    我假设当提要为空时节点列表将为空?然后它看起来像这样:

    public class CustomizedListView extends Activity {
    
        private Button btnLoadMore;
    
        public void onCreate(){
            btnLoadMore = new Button(this);
            <do stuff>
            btnLoadMore.setOnClickListener(new View.OnClickListener() {
    
               @Override
               public void onClick(View arg0) {
                   // Starting a new async task
                   new LoadMoreListView().execute();
               }
            });
    
            new LoadMoreListView().execute();// execute the AsyncTask once in the onCreate, so you don't have to duplicate the code here to load the listview.
    
        }
    
        private class LoadMoreListView extends AsyncTask<Void, Void, Boolean> {
    
            @Override 
            protected void onPreExecute() {
                < Show dialog>;
            }
    
            @Override
            protected Void doInBackground(Void... unused) {
               Boolean listIsEmpty;
    
               < Page request>;
               < Retrieve element list>;
               < If element list size == 0, listIsEmpty = true; return listIsEmpty>;
    
               < Process elements, fill list etc.>;
               < End of doInBackground, listIsEmpty = false; return listIsEmpty>;
    
            }
    
            @Override
            protected void onPostExecute(Boolean listIsEmpty) {
                < If listIsEmpty == true -> btnLoadMore.setVisibility(View.GONE);>
                < Close dialog>
            }
        }
    }
    }
    

    【讨论】:

    • 只检查元素列表是否为空,在 NodeList nl = doc.getElementsByTagName(KEY_SONG); : if(nl.getLenght()==0) 返回 listIsEmpty=true
    • 我认为这不是您的完整代码,该按钮仍定义在 onCreate 方法中,因此无法从 AsyncTask 访问。你现在也有两个 onPostExecute 方法,只有一个带有布尔参数的方法被调用..所以将dismissDialog移到这个。此外,您将 listIsEmpty 布尔值初始化为 true,这应该是 false .. 因为您应该只在检查列表是否为空后将其设置为 true。它现在将始终返回 true。你在正确的轨道上。
    • 相当多地清理了你的代码:pastie.org/private/shrpac51lbgmqj3t9tiwgg 特别是通过创建一个 bindView 方法来将所有 UI 元素绑定到它们的 View 对象,而不是每次选择一行时都这样做。如果节点列表大小在为空时确实为 0,则现在应该禁用该按钮。不能再帮你了。编辑:哎呀,这行不通,已经想知道所有这些文本视图来自哪里..列表中的每一行都包含所有这些文本视图?那我做的就不行了..
    • 您好,我已经使用了您的代码。我必须运行应用程序,这意味着只有黑屏。请参阅此截屏视频:screencast.com/t/pSBJKSSC
    • 哦,不太好接受,然后当我尝试为您提供更多帮助时不接受。我的回答回答了您的问题,只是我为使其更清洁而更改的其余代码不起作用。
    【解决方案2】:

    我使用这种方式实现了更多负载,我不使用页脚视图

    public boolean mHasLoadMore = false;
    
        class MyAdapter extends ArrayAdapter implements OnItemClickListener{
    
            public MyAdapter(Context context, int textViewResourceId) {
                super(context, textViewResourceId);
                // TODO Auto-generated constructor stub
            }
    
            public int getTotal(){
                return super.getCount();
            }
            @Override
            public int getCount() {
    
                if(super.getCount()>0)
                    return super.getCount()+1;
                else
                    return 0;
    
            }
    
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
    
                if( getTotal() == (position+1) && mHasLoadMore ){
    
                    TextView loadMoreView = new TextView(getContext());
                    loadMoreView.setText("Load More");
                    return loadMoreView;
                }              
                else {
                    View theView = new View(getContext());
                    // inflate & add what you need for item view here you can modify it to reuse convertView also
                    return theView;
                }   
    
            }
    
            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int position,
                    long id) {
    
                if( getTotal() == (position+1) && mHasLoadMore ){
    
                    // load more button clicked do handling for load more launch async 
                    //task to do load more after that if found 0 result change mHasLoadMore to false 
                    //& call notifydatadetchanged               
                }
                else
                {
                    // handle item click here  
                }
    
            }
    
    
    
        } 
    

    在加载数据并调用 notifydatasetchanged 时,第一次将此类适配器用于您的列表视图并设置 mHasLoadMore 的值

    【讨论】:

    • 这是用于列表视图底部的加载更多按钮(或者更确切地说是可点击的文本视图)?我认为这并不是他问题的真正答案,他还想知道如何检查条件并将更改传递给 UI。但仍然是 loadMore 按钮的好方法。
    • 糟糕,完全错过了 OP 中的部分,就像在您的示例中一样,LV 底部的按钮。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-07
    • 2011-01-23
    • 1970-01-01
    相关资源
    最近更新 更多