XML Parseo with use of RecyclerView

1

I'm doing an app that consumes data from an xml that comes from the internet, this consumed data is shown in CardViews inside a RecyclerView so when you click on the image of the CardView another screen with the details is opened (Image, title of news and content of the news), in the cardview only show image, date / time, and title.

The details of the news are captured from another XML file and that the route is armed based on a unique number that comes in the first XML. Unfortunately I have not managed to get me to show the details of the news in a layout that simply has ImageView, TextView (title) and TextView (full news).

This is the MyAdapter class where I set.

public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
Context c;
ArrayList<Article> articles;


public MyAdapter(Context c, ArrayList<Article> articles) {
    this.c = c;
    this.articles = articles;
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v= LayoutInflater.from(c).inflate(R.layout.model,parent,false);
    return new MyViewHolder(v);
}

@Override
   public void onBindViewHolder(final MyViewHolder holder, final int 
position) 
  {
     final Article article=articles.get(position);
    System.out.println("MyAdater, position es: "+position);
     String title=article.getTitle();
    //String desc=article.getDescription();
    String dateFecha=article.getTsFecha();
    String dateHora=article.getTsHora();
    String imageUrl=article.getImageUrl();
    final String tsarticle=article.getTsArticle();

    holder.titleTxt.setText(title);
    holder.dateFechaTxt.setText(dateFecha);
    holder.dateHoraTxt.setText(dateHora);


    String baseUrl = "http://www.ejemplo.cl";
    String cadenaUrl = baseUrl+imageUrl;

   // Log.i("valor total cadena",": "+cadenaUrl);
    Picasso.with(c).load(cadenaUrl).into(holder.img);

    holder.img.setOnClickListener(new View.OnClickListener(){

        @Override
        public void onClick(View v) {

          Intent intent = new Intent(c, PictureDetailActivity.class);

            if (Build.VERSION.SDK_INT>= Build.VERSION_CODES.LOLLIPOP){

                Explode explode = new Explode();
                explode.setDuration(1000);
                //si estuvieramos en una actividad no sería necesario 
  agregar activity.getWindow, solo getWindow
                //activity.getWindow()

                //como personalizamos la duración de la transición(el objeto 
   Explode), debemos colocar el nombre de la clase instanciada,
                // .setExitTransition(explode);
                // de lo contrario solo sería .setExitTransition(new 
   Explode()); y toma los valores por defecto de Explode.

           //  c.getWindow().setExitTransition(explode);
               // activity.startActivity(intent, ActivityOptionsCompat.
                 //       

makeSceneTransitionAnimation(activity,v,activity.getString
(R.string.transitonname_picture))
                 //       .toBundle());



              //  Log.i("el ts es "," :"+tsarticle.toString());
                intent.putExtra("article_object", article);
               c.startActivity(intent);
            }else {
                c.startActivity(intent);
            }
        }
    });
  }
      @Override
    public int getItemCount() {
       return articles.size();
    }

  }

This is the RSSParser class, where I parse the XML file (at this moment I will not leave the class where I make the HttpURLConnection connection)

public class RSSParserDetail implements Serializable{

    Context c;

private InputStream urlStream;
private XmlPullParserFactory factory;
private XmlPullParser parser;

private List<ArticleDetail> rssFeedList;
private ArticleDetail rssFeed;

private String urlString;
private String tagName;

private  String title;
private String link;
private String description;

public static final String ITEM = "artic_data";
public static final String CHANNEL = "public";
public static final String TITLE = "_txt_titular";
public static final String LINK = "fotofija_port_649x365";
public static final String DESCRIPTION = "vtxt_cuerpo";


  public RSSParserDetail( String urlString ) {
      this.urlString=urlString;
}

 public static InputStream downloadUrl(String urlString) throws IOException 
 {

    URL url = new URL(urlString);
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();

    conn.setRequestMethod("GET");
    conn.setDoInput(true);
    conn.connect();

    InputStream stream = conn.getInputStream();
    return stream;
 }

  public List<ArticleDetail> parse() {
    try {
        int count = 0;
        factory = XmlPullParserFactory.newInstance();
        parser = factory.newPullParser();
        urlStream = downloadUrl(urlString);
        parser.setInput(urlStream, null);
        int eventType = parser.getEventType();
        boolean done = false;
        rssFeed = new ArticleDetail();
        rssFeedList = new ArrayList<ArticleDetail>();
        while (eventType != XmlPullParser.END_DOCUMENT && !done) {
            tagName = parser.getName();

            switch (eventType) {
                case XmlPullParser.START_DOCUMENT:
                    break;
                case XmlPullParser.START_TAG:
                    if (tagName.equals(ITEM)) {
                        rssFeed = new ArticleDetail();
                    }
                    if (tagName.equals(TITLE)) {
                        title = parser.nextText().toString();
                        System.out.println("Muestrame el titulo, 
      RSSParserDetail: "+title);
                    }
                    if (tagName.equals(LINK)) {
                        link = parser.nextText().toString();
                    }
                    if (tagName.equals(DESCRIPTION)) {
                        description = parser.nextText().toString();
                    }

                    break;
                case XmlPullParser.END_TAG:
                    if (tagName.equals(CHANNEL)) {
                        done = true;
                    } else if (tagName.equals(ITEM)) {
                        rssFeed=new ArticleDetail(title,link,description);
                        rssFeedList.add(rssFeed);
                    }
                    break;
            }
            eventType = parser.next();
            }
        } catch (Exception e) {
        e.printStackTrace();
       }

       return rssFeedList;
   }

}

When I click on the image of the CardView, it sends me through an Intent PictureDetailActivity, and since the file to be parsed is different (in tag and content) to the previous one I had to make another class called RSSParserDetail.

This is the PictureDetailActivity class.

public class PictureDetailActivity extends AppCompatActivity implements 
Serializable{

RSSParserDetail rssParserDetail;
private List<ArticleDetail> mRssFeedList;
Context c;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
 //setContentView(R.layout.activity_picture_detail);
    setElement();
   // showToolbar("",true);

    getWindow().setEnterTransition(new Fade());
    c = getApplicationContext();

 }
     public void setElement (){
      Article article = (Article) 
     getIntent().getSerializableExtra("article_object");

     //Armando Url para capturar archivo de articulo en servidor
    String tsArticle = article.getTsArticle();
    String baseUrl="https://www.cooperativa.cl/noticias/site/artic/";
    String titleDetail = article.getTitle();
    String dataTs = tsArticle.substring(0,8);
    String aammdd = dataTs;
    String directorioXml="/xml/";
    String finalUrl= tsArticle+".xml";
    String linkXml=baseUrl+aammdd+directorioXml+finalUrl;
    //***********************************************************
    String linkPaso="http://especiales2.cooperativa.cl/
    2017/pruebas/rvargas/prontus_art_view_xml.xml";
    System.out.println("estoy en PictureDetailActivity");

   new DoRssFeedTask().execute(linkPaso);
   }

   public class DoRssFeedTask extends AsyncTask<String, Void, 
    List<ArticleDetail>> {
    ProgressDialog prog;
    String jsonStr = null;
    Handler innerHandler;

    @Override
    protected void onPreExecute() {
        prog = new ProgressDialog(PictureDetailActivity.this);
        prog.setMessage("Loading....");
        prog.show();
    }

    @Override
    protected List<ArticleDetail> doInBackground(String... params) {
        for (String urlVal : params) {
            rssParserDetail = new RSSParserDetail(urlVal);
        }
       // mRssFeedList = mNewsFeeder.parse();
        mRssFeedList=rssParserDetail.parse();
        return mRssFeedList;
    }

    @Override
    protected void onPostExecute(List<ArticleDetail> result) {
        prog.dismiss();
     // new MyAdapterDetail();
        Intent intent = new Intent(PictureDetailActivity.this, 
  MyAdapterDetail.class);
         startActivity(intent);

        System.out.println("PictureDetailActivity onPostExecute");
    }

    @Override
    protected void onProgressUpdate(Void... values) {
    }
}

public void showToolbar(String tittle, boolean upButton/*, View view*/){
    /*se crea el metodo showtoolbar para traer toolbar según maqueta de 
diseño*/
    /*este metodo no debe llevar view porque estamos en cotexto de 
 activity*/

    /*Estamos en contexto de Activity, es por eso que no debe de llevar el 
 código ((AppCompatActivity)getActivity())
    al llevar este código a un fragment si debe llevar ese codigo
     */

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    getSupportActionBar().setTitle(tittle);
    getSupportActionBar().setDisplayHomeAsUpEnabled(upButton);
    CollapsingToolbarLayout collapsingtoolbarlayout =  
  (CollapsingToolbarLayout) findViewById(R.id.collapsingToolbar);/*aún no 
   funcional, sea crea para el proximo curso*/

   }

}

And this is the RSSParserDetail class.

public class RSSParserDetail implements Serializable{

Context c;

private InputStream urlStream;
private XmlPullParserFactory factory;
private XmlPullParser parser;

private List<ArticleDetail> rssFeedList;
private ArticleDetail rssFeed;

private String urlString;
private String tagName;

String title;
String link;
String description;

public static final String ITEM = "artic_data";
public static final String CHANNEL = "public";
public static final String TITLE = "_txt_titular";
public static final String LINK = "fotofija_port_649x365";
public static final String DESCRIPTION = "vtxt_cuerpo";


  public RSSParserDetail( String urlString ) {
      this.urlString=urlString;
}

public static InputStream downloadUrl(String urlString) throws IOException {

    URL url = new URL(urlString);
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();

    conn.setRequestMethod("GET");
    conn.setDoInput(true);
    conn.connect();

    InputStream stream = conn.getInputStream();
    return stream;
}

public List<ArticleDetail> parse() {
    try {
        int count = 0;
        factory = XmlPullParserFactory.newInstance();
        parser = factory.newPullParser();
        urlStream = downloadUrl(urlString);
        parser.setInput(urlStream, null);
        int eventType = parser.getEventType();
        boolean done = false;
        rssFeed = new ArticleDetail();
        rssFeedList = new ArrayList<ArticleDetail>();
        while (eventType != XmlPullParser.END_DOCUMENT && !done) {
            tagName = parser.getName();

            switch (eventType) {
                case XmlPullParser.START_DOCUMENT:
                    break;
                case XmlPullParser.START_TAG:
                    if (tagName.equals(ITEM)) {
                        rssFeed = new ArticleDetail();
                    }
                    if (tagName.equals(TITLE)) {
                        title = parser.nextText().toString();
                    }
                    if (tagName.equals(LINK)) {
                        link = parser.nextText().toString();
                    }
                    if (tagName.equals(DESCRIPTION)) {
                        description = parser.nextText().toString();
                    }

                    break;
                case XmlPullParser.END_TAG:
                    if (tagName.equals(CHANNEL)) {
                        done = true;
                    } else if (tagName.equals(ITEM)) {
                        rssFeedList.add(rssFeed);
                    }
                    break;
            }
            eventType = parser.next();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

    return rssFeedList;
  }

}

This is the MyAdapterDetail class, which is where I send the elements to begin setting.

public class MyAdapterDetail extends AppCompatActivity implements 
    Serializable {
     //ArrayList<RSSParserDetail> articles;

     //ArticleDetail articles = new ArticleDetail();
    //ArrayList<ArticleDetail> articles;
    Context c;
   //ArticleDetail articles;
   MyViewHolderDetail myViewHolderDetail;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
     // ArticleDetail article=articles.get(0);

  //articles= (ArrayList<ArticleDetail>) 
    getIntent().getSerializableExtra("objeto");
   // System.out.println("MyAdapterDetail tamaño de arreglo que llega es de: 
    "+articles.size());

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_picture_detail);
    showToolbar("",true);
    System.out.println("Estoy en el AdapterDetail");
    setElementDetail();
   }

    public void setElementDetail(){
    //System.out.println("MyAdapterDetail en setElemetDetail, el tamaño de 
     arreglo es: "+articles.size());

     ArticleDetail article = new ArticleDetail();
     //String imageUrl=article.getImageUrlDetail();
     String title=article.getTitleDetail();
    //String desc=article.getContDetail();
    String baseUrl = "http://www.cooperativa.cl";
   //String cadenaUrl = baseUrl+imageUrl;

   //Picasso.with(c).load(cadenaUrl).into(myViewHolderDetail.img);
  //myViewHolderDetail.titleTxtDetail.setText(title);
 //myViewHolderDetail.titleDetail.setText(desc);

    //System.out.println("Mi cadena URL es: "+cadenaUrl);
    System.out.println("Mi titulo es: "+title);
  //System.out.println("Mi Detalle es: "+desc);
 }

 public void showToolbar(String tittle, boolean upButton/*, View view*/){
    /*se crea el metodo showtoolbar para traer toolbar según maqueta de 
     diseño*/
    /*este metodo no debe llevar view porque estamos en cotexto de 
     activity*/

    /*Estamos en contexto de Activity, es por eso que no debe de llevar el 
       código ((AppCompatActivity)getActivity())
    al llevar este código a un fragment si debe llevar ese codigo
     */

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    getSupportActionBar().setTitle(tittle);
    getSupportActionBar().setDisplayHomeAsUpEnabled(upButton);
    CollapsingToolbarLayout collapsingtoolbarlayout =  
    (CollapsingToolbarLayout) findViewById(R.id.collapsingToolbar);/*aún no 
    funcional, sea crea para el proximo curso*/
     }
   }



06-13 17:23:45.032 28631-28631/cl.cooperativa.readxmlfrominternetmaterial 
                               I/System.out: Estoy en el AdapterDetail
06-13 17:23:45.032 28631-28631/cl.cooperativa.readxmlfrominternetmaterial 
                               I/System.out: Mi titulo es: null

I tried to detail as much as possible my problem, I remain attentive to any comment. Thank you very much.

    
asked by Rodrigo 13.06.2017 в 17:53
source

1 answer

0

Error occurs in class PictureDetailActivity :

NullPointerException: Attempt to invoke virtual method 'void android.content.Context.startActivity(android.content.Intent)' on a null object reference

The variable c that the context should have, has value null when you try to perform startActivity() :

c.startActivity(intent);

You can assign the value of c within onCreate() in this way:

  c = this; //*** Asigna valor del contexto.

or like this:

  c = getApplicationContext(); //*** Asigna valor del contexto.

It is important to also comment that if you are in an Activity, you do not need the context to call startActivity() , simply:

 startActivity(intent);

for example:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
 //setContentView(R.layout.activity_picture_detail);
    setElement();
   // showToolbar("",true);

    getWindow().setEnterTransition(new Fade());

    c = getApplicationContext(); //*** Asigna valor del contexto.

 }
    
answered by 13.06.2017 в 18:10