【问题标题】:Listview item opening url of article文章的Listview项目打开url
【发布时间】:2015-06-04 04:57:45
【问题描述】:

我正在尝试设置 onitemclicklistener 以注册单击了哪个列表视图项目,然后获取保存在链接中的该文章的 url,然后在新活动中打开具有该 url 的网页。我尝试的一切都会引发错误,使其无法编译。目前,onitemclicklistener 在holder.articleLink.setText(currentItem.get("link")); 以及下方我在最底部的 holder 部分中声明 setText 的地方抛出错误。

public class L {
public static void m(String message)
{
    Log.d("test", message);
}
public static void s(Context context, String message)
{
    Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
}
}

public class MainActivity extends ActionBarActivity implements ResultsCallback {

PlaceholderFragment taskFragment;
ListView articlesListView;


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

    if (savedInstanceState == null) {
        taskFragment = new PlaceholderFragment();
        getFragmentManager().beginTransaction().add(taskFragment, "MyFragment").commit();
    } else {

        taskFragment = (PlaceholderFragment) getFragmentManager().findFragmentByTag("MyFragment");
    }
    taskFragment.startTask();

    articlesListView = (ListView) findViewById(R.id.articlesListView);
}

public static class PlaceholderFragment extends Fragment {

    BsuNewsTask downloadTask;
    ResultsCallback callback;

    public PlaceholderFragment() {
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        callback = (ResultsCallback) activity;
        if(downloadTask != null) {
            downloadTask.onAttach(callback);
        }
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        setRetainInstance(true);
    }

    public void startTask()
    {
        if(downloadTask != null) {
            downloadTask.cancel(true);
        } else {
            downloadTask = new BsuNewsTask(callback);
            downloadTask.execute();
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        callback = null;
        if(downloadTask!=null) {
            downloadTask.onDetach();
        }
    }
}



public static class BsuNewsTask extends
        AsyncTask<Void, Void, ArrayList<HashMap<String, String>>> {

    ResultsCallback callback= null;

    public BsuNewsTask(ResultsCallback callback) {
        this.callback = callback;
    }

    public  void onAttach(ResultsCallback callback) {

        this.callback = callback;
    }

    public void onDetach() {

        callback = null;
    }

    @Override
    protected void onPreExecute() {
        if (callback != null) {
            callback.onPreExecute();
        }
    }

    @Override
    protected ArrayList<HashMap<String, String>> doInBackground(Void... params) {
        String downloadURL="http://cms.bsu.edu/news/rss";
        ArrayList<HashMap<String, String>> results = new ArrayList<>();
        try {
            URL url=new URL(downloadURL);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            InputStream inputStream = connection.getInputStream();
            results = processXML(inputStream);
        } catch (Exception e) {
            L.m(e + "");

        }
        return results;
    }

    @Override
    protected void onPostExecute(ArrayList<HashMap<String, String>> result) {
        if (callback != null) {
            callback.onPostExecute(result);
        }
    }

    public ArrayList<HashMap<String, String>> processXML(InputStream inputStream) throws Exception {
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
                .newInstance();
        DocumentBuilder documentBuilder = documentBuilderFactory
                .newDocumentBuilder();
        Document xmlDocument = documentBuilder.parse(inputStream);
        Element rootElement = xmlDocument.getDocumentElement();
        //print rootelement name in logcat
        //L.m("" + rootElement.getTagName());
        NodeList itemsList = rootElement.getElementsByTagName("item");
        NodeList itemChildren = null;
        Node currentItem = null;
        Node currentChild = null;
        ArrayList<HashMap<String, String>> results = new ArrayList<>();
        HashMap<String, String> currentMap = null;

        for(int i=0; i < itemsList.getLength(); i++) {
            currentItem = itemsList.item(i);
            itemChildren = currentItem.getChildNodes();

            currentMap = new HashMap<>();
            for (int j=0; j < itemChildren.getLength(); j++) {
                currentChild=itemChildren.item(j);
                if(currentChild.getNodeName().equalsIgnoreCase("title")) {
                    //L.m(currentChild.getTextContent());
                    currentMap.put("title", currentChild.getTextContent());
                }
                if(currentChild.getNodeName().equalsIgnoreCase("description")) {
                    //L.m(currentChild.getTextContent());
                    currentMap.put("description", currentChild.getTextContent());
                }
                if(currentChild.getNodeName().equalsIgnoreCase("link")) {
                    //L.m(currentChild.getTextContent());
                    currentMap.put("link", currentChild.getTextContent());
                }
                if(currentChild.getNodeName().equalsIgnoreCase("pubDate")) {
                    //L.m(currentChild.getTextContent());
                    currentMap.put("pubDate", currentChild.getTextContent());
                }
            }
            if(currentMap != null && !currentMap.isEmpty()) {
                results.add(currentMap);
            }

        }
        return results;

    }
}


@Override
public void onPreExecute() {

}

@Override
public void onPostExecute(ArrayList<HashMap<String, String>> results) {

    articlesListView.setAdapter(new MyAdapter(this, results));
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

public void onListItemClick(ListView l, View v, int position, long id) {
    MyAdapter adapter = (MyAdapter)l.getAdapter();
    Uri uri = Uri.parse(adapter.dataSource.get(position).get("link"));
    Intent intent = new Intent(Intent.ACTION_VIEW, uri);
    startActivity(intent);
}
}

interface ResultsCallback {
public void onPreExecute();

public void onPostExecute(ArrayList<HashMap<String, String>> results);
}
class MyAdapter extends BaseAdapter{

ArrayList<HashMap<String, String>> dataSource = new ArrayList<>();
Context context;
LayoutInflater layoutInflater;

public MyAdapter(Context context, ArrayList<HashMap<String, String>> dataSource) {
    this.context=context;
    this.dataSource = dataSource;
    layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
    return dataSource.size();
}

@Override
public Object getItem(int position) {
    return dataSource.get(position);
}

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

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View row = convertView;
    MyHolder holder = null;
    if(row == null){
        row = layoutInflater.inflate(R.layout.custom_row, parent, false);
        holder = new MyHolder(row);
        row.setTag(holder);
    }
    else{
        holder = (MyHolder) row.getTag();

    }
    HashMap<String, String> currentItem = dataSource.get(position);
    holder.articleTitleText.setText(currentItem.get("title"));
    holder.articleDescriptionText.setText(currentItem.get("description"));
    holder.articleDateText.setText(currentItem.get("pubDate"));
    return row;

}
}
class MyHolder
{
TextView articleTitleText;
TextView articleDescriptionText;
TextView articleDateText;

public MyHolder(View view) {
    articleTitleText=(TextView) view
            .findViewById(R.id.articleTitleText);
    articleDescriptionText = (TextView) view
            .findViewById(R.id.articleDescriptionText);
    articleDateText = (TextView) view
            .findViewById(R.id.articleDateText);


}
}

【问题讨论】:

  • 什么是 L.m(e + ""); 中的“L”?
  • 这是一个教程使用的类,它使用public static void m(String message) {Log.d("test", message); } public static void s(Context context, String message)调用logcat
  • 为一直在询问的人添加了日志类
  • 为什么要在 URL 对象中调用 setText 方法?例如,您用于 TextView 和 EditText 的这种方法。
  • 这只是我尝试过的许多事情之一,它使用该链接使程序崩溃,所以我已经删除了它,它恰好是我在询问之前自己做的最后一个。跨度>

标签: android listview arraylist xml-parsing


【解决方案1】:

编译你的代码后,我看到你必须做一些修改:

  • ListView中设置item点击监听,这样:

    articlesListView.setOnItemClickListener(this);
    
  • 之后,你必须让你的activity实现OnItemClickListener,这样:

    public class MainActivitySO extends ActionBarActivity implements ResultsCallback, 
    AdapterView.OnItemClickListener {
    
  • 然后,您将必须在您的活动中实现方法onItemClick。因此,在这种方法中,您可以使用已有的代码:

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        MyAdapter adapter = (MyAdapter) articlesListView.getAdapter();
        Uri uri = Uri.parse(adapter.dataSource.get(position).get("link"));
        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
        startActivity(intent);
    }
    

【讨论】:

  • 在添加articlesListView = (ListView) findViewById(R.id.articlesListView);和所有这些代码后,编译并加载了网页中的文章
  • 您在代码的第一个实现中没有它?
  • 看看它现在是如何编译的
【解决方案2】:

尝试从您的数据源获取链接:

public void onListItemClick(AdapterView<?> parent, View view, int position, long id) {
    ListView l = (ListView) parent;
    MyAdapter adapter = (MyAdapter)l.getAdapter();
    Uri uri = Uri.parse(adapter.dataSource.get(position).get("link"));
    Intent intent = new Intent(Intent.ACTION_VIEW, uri);
    startActivity(intent);
}

但首先,实现 AdapterView.OnItemClickListener 接口(抱歉,我无法弄清楚您的 onListItemClick 方法是如何被调用的。如果您已经这样做了,请忽略它)

public class MainActivity extends ActionBarActivity implements ResultsCallback,AdapterView.OnItemClickListener {

 @Override
 protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_main);
     articlesListView = (ListView) findViewById(R.id.articlesListView);
     articlesListView.setOnItemClickListener(this);
}

【讨论】:

  • 我试过这段代码,在公共类 MainActivity 部分它说 Class 'MainActivity' 必须声明为抽象或实现抽象方法 'onItemClick(AdapterView>, View, int, long)' in 'onItemClickListener' 底部的这个也是说由于实现错误而可能无法应用适配器视图
  • 我尝试实现它,它想让类抽象,所以我这样做并设置了 view.onclicklistener 。然后我不得不将 listitemclick 更改为 AdapterView&lt;?&gt; parent, View v, int position, long l 以满足错误,当我尝试运行程序时它只是说它停止并且根本不显示列表视图
  • 刚刚收到一堆 logcat 错误,太长了无法粘贴它们,我把它放在 pastebin 上。 pastebin.com/wA1a1QPF
  • 您不必将类抽象化。如答案所示,您已经让您的类实现了 AdapterView.OnItemClickListener。
  • 不得将 MainActivity 更改为 abstract。我改一下答案,也许你会觉得更简单……
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-30
  • 2018-04-13
  • 1970-01-01
  • 2011-03-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多