2017-03-22 122 views
6

我收到此错误。错误地覆盖包裹

03-22 11:41:20.439 20933-20933/com.androidcss.jsonexample E/RecyclerView:没有附加适配器;跳过布局 03-22 11:41:20.760 20933-20933/com.androidcss.jsonexample W/art:在Android 4.1之前,方法int android.support.v7.widget.ListViewCompat.lookForSelectablePosition(int,boolean)将被错误地覆盖在android.widget.ListView

包-私有方法

MainActivity.java

package com.androidcss.jsonexample; 

import android.app.ProgressDialog; 
import android.os.AsyncTask; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.support.v7.widget.LinearLayoutManager; 
import android.support.v7.widget.RecyclerView; 
import android.widget.Toast; 
import org.json.JSONArray; 
import org.json.JSONException; 
import org.json.JSONObject; 
import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.net.HttpURLConnection; 
import java.net.MalformedURLException; 
import java.net.URL; 
import java.util.ArrayList; 
import java.util.List; 

public class MainActivity extends AppCompatActivity { 

    // CONNECTION_TIMEOUT and READ_TIMEOUT are in milliseconds 
    public static final int CONNECTION_TIMEOUT = 10000; 
    public static final int READ_TIMEOUT = 15000; 
    private RecyclerView mRVFishPrice; 
    private AdapterFish mAdapter; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     //Make call to AsyncTask 
     new AsyncLogin().execute(); 


    } 

    private class AsyncLogin extends AsyncTask<String, String, String> { 
     ProgressDialog pdLoading = new ProgressDialog(MainActivity.this); 
     HttpURLConnection conn; 
     URL url = null; 

     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 

      //this method will be running on UI thread 
      pdLoading.setMessage("\tLoading..."); 
      pdLoading.setCancelable(false); 
      pdLoading.show(); 

     } 

     @Override 
     protected String doInBackground(String... params) { 
      try { 

       // Enter URL address where your json file resides 
       // Even you can make call to php file which returns json data 
       url = new URL("https://newsapi.org/v1/articles?source=the-next-web&sortBy=latest&apiKey=bdba5de1b490495796a1595f77ed3f37"); 

      } catch (MalformedURLException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
       return e.toString(); 
      } 
      try { 

       // Setup HttpURLConnection class to send and receive data from php and mysql 
       conn = (HttpURLConnection) url.openConnection(); 
       conn.setReadTimeout(READ_TIMEOUT); 
       conn.setConnectTimeout(CONNECTION_TIMEOUT); 
       conn.setRequestMethod("GET"); 

       // setDoOutput to true as we recieve data from json file 
       conn.setDoOutput(true); 

      } catch (IOException e1) { 
       // TODO Auto-generated catch block 
       e1.printStackTrace(); 
       return e1.toString(); 
      } 

      try { 

       int response_code = conn.getResponseCode(); 

       // Check if successful connection made 
       if (response_code == HttpURLConnection.HTTP_OK) { 

        // Read data sent from server 
        InputStream input = conn.getInputStream(); 
        BufferedReader reader = new BufferedReader(new InputStreamReader(input)); 
        StringBuilder result = new StringBuilder(); 
        String line; 

        while ((line = reader.readLine()) != null) { 
         result.append(line); 
        } 

        // Pass data to onPostExecute method 
        return (result.toString()); 

       } else { 

        return ("unsuccessful"); 
       } 

      } catch (IOException e) { 
       e.printStackTrace(); 
       return e.toString(); 
      } finally { 
       conn.disconnect(); 
      } 


     } 

     @Override 
     protected void onPostExecute(String result) { 

      //this method will be running on UI thread 

      pdLoading.dismiss(); 
      List<Item> data=new ArrayList<>(); 

      pdLoading.dismiss(); 
      try { 

       JSONObject object= new JSONObject(result); 
       JSONArray array = object.getJSONArray("articles"); 

       // Extract data from json and store into ArrayList as class objects 
       for(int i=0;i<array.length();i++){ 
        JSONObject json_data = array.getJSONObject(i); 
        Item item= new Item(); 
        item.name= json_data.getString("title"); 

        data.add(item); 
       } 

       // Setup and Handover data to recyclerview 
       mRVFishPrice = (RecyclerView)findViewById(R.id.fishPriceList); 
       mAdapter = new AdapterFish(MainActivity.this, data); 
       mRVFishPrice.setAdapter(mAdapter); 
       mRVFishPrice.setLayoutManager(new LinearLayoutManager(MainActivity.this)); 

      } catch (JSONException e) { 
       Toast.makeText(MainActivity.this, e.toString(), Toast.LENGTH_LONG).show(); 
      } 

     } 

    } 
} 

AdapterFish.java

package com.androidcss.jsonexample; 

import android.content.Context; 
import android.support.v4.content.ContextCompat; 
import android.support.v7.widget.RecyclerView; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.TextView; 
import com.bumptech.glide.Glide; 
import java.util.Collections; 
import java.util.List; 

public class AdapterFish extends RecyclerView.Adapter<RecyclerView.ViewHolder> { 

    private Context context; 
    private LayoutInflater inflater; 
    List<Item> data= Collections.emptyList(); 
    Item current; 
    int currentPos=0; 

    // create constructor to innitilize context and data sent from MainActivity 
    public AdapterFish(Context context, List<Item> data){ 
     this.context=context; 
     inflater= LayoutInflater.from(context); 
     this.data=data; 
    } 

    // Inflate the layout when viewholder created 
    @Override 
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View view=inflater.inflate(R.layout.card, parent,false); 
     MyHolder holder=new MyHolder(view); 
     return holder; 
    } 

    // Bind data 
    @Override 
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { 

     // Get current position of item in recyclerview to bind data and assign values from list 
     MyHolder myHolder= (MyHolder) holder; 
     Item current=data.get(position); 

     myHolder.name.setText(current.getName()); 

     // load image into imageview using glide 
     /*Glide.with(context).load("http://192.168.1.7/test/images/" + current.fishImage) 
       .placeholder(R.drawable.ic_img_error) 
       .error(R.drawable.ic_img_error) 
       .into(myHolder.ivFish);*/ 

    } 

    // return total item from List 
    @Override 
    public int getItemCount() { 
     return data.size(); 
    } 


    class MyHolder extends RecyclerView.ViewHolder{ 

     TextView name; 


     // create constructor to get widget reference 
     public MyHolder(View itemView) { 
      super(itemView); 
      name = (TextView)itemView.findViewById(R.id.name); 


     } 

    } 

} 

Item.java

package com.androidcss.jsonexample; 

public class Item { 

    String name; 

    public String getName() { 
     return name; 
    } 
} 
+0

在'setAdapter'之前调用'LayoutManager'到'recyclerview'步骤应该像实例化'recyclerview'>然后设置'LayoutManager'到它>然后'setAdapter' –

+0

我刚试过。不工作。 –

+0

请使用Volley进行API调用,而不是实现自定义后台任务并搞乱实际代码。排球更清洁,更高效。而对于你所问的问题,我已经提供了答案。 –

回答

2

setAdapter之前需要setLayoutManager

+2

我有这个,但仍然出现错误。 – Micer

0

您正在初始化RecyclerViewAsynTask,这意味着您的ReyclerView尚未准备好创建视图时。

进行以下更改。

//make list as global variable 
private List<Item> data; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    //view should be initialized in UI thread 
    data=new ArrayList<>(); 
    mRVFishPrice = (RecyclerView)findViewById(R.id.fishPriceList); 
    mAdapter = new AdapterFish(MainActivity.this, data); 
    mRVFishPrice.setLayoutManager(new LinearLayoutManager(MainActivity.this)); 
    mRVFishPrice.setAdapter(mAdapter); 

    //Make call to AsyncTask 
    new AsyncLogin().execute(); 
} 

然后在你的onPostExecute

更换 -

mRVFishPrice = (RecyclerView)findViewById(R.id.fishPriceList); 
mAdapter = new AdapterFish(MainActivity.this, data); 
mRVFishPrice.setAdapter(mAdapter); 
mRVFishPrice.setLayoutManager(new LinearLayoutManager(MainActivity.this)); 

mAdapter.notifyDatasetChanged(); 

也,请务必从postexecute和MAK删除List<Item> data Ë其全球

并请使用排,使API调用,而不是实现自定义 后台任务。 Volley异步处理API调用,而不是 搞乱您的实际代码。

+0

这有帮助。我将在未来的项目中使用排球。我面临着另一个问题。我完全按照你的说法做了,当我运行应用程序时,我得到了这个错误:“org.json.JSONException:类型java.lang.String的值不能被转换为JSONObject”。在监视器中,我看到:“03-24 22:45:12.696 6213-6213/com.androidcss.jsonexample W/art:在Android 4.1之前,方法int android.support.v7.widget。ListViewCompat.lookForSelectablePosition(int,boolean)会错误地覆盖android.widget.ListView中的包私有方法“ –