4

I am struggling with my custom listview. I want to populate my list view with my custom row.xml file which contains five textviews. I have a text file mytextfile.txt in the raw folder. It look like this:

SUN-9-JULY-On Sale Now-New York, Time Square
SAT-15-JULY-On Sale Now-London, National Gallery
MON-23-JULY-On Sale Now-Paris, The Eiffel Tower
// More lines here...

As you can see I create a string array from each line (using split method with "-") and put all string arrays inside a ArrayList. I don't know how to create my CustomAdapter class to make this work. My other files looks like...

Concerts.java

public class Concerts {

    private List<String[]> mAllConcerts;

    public List<String[]> getAllConcerts() {
        return mAllConcerts;
    }

    public Concerts() {
        mAllConcerts = new ArrayList<>();
        InputStream inputStream = null;
        InputStreamReader inputReader = null;
        BufferedReader bufferedReader;
        String line;
        try {
            inputStream = MainActivity.getGlobalContext().getResources()
                    .openRawResource(R.raw.mytextfile.txt);
            inputReader = new InputStreamReader(inputStream);
            bufferedReader = new BufferedReader(inputReader);
            while (( line = bufferedReader.readLine()) != null) {
                String [] mConcertDetails = line.split("-");
                mAllConcerts.add(mConcertDetails);
            }
        }
        catch (IOException e) {
            // cathing...
        }
        finally {
             // closing...
        }
    }
}

CustomAdapter.java (I don't even know if I am on the right path here)

public class CustomAdapter extends ArrayAdapter<String> {

    TextView concertDayName;
    TextView concertDayNumber;
    TextView concertMonthName;
    TextView concertOnSaleNow;
    TextView concertPlaceName;

    Concerts concerts;

    public CustomAdapter(Context context, String[] values) {
        super(context, R.layout.concert_row, values);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = LayoutInflater.from(getContext());
        View view = inflater.inflate(R.layout.concert_row, parent, false);

        concerts = new Concerts();

        concertDayName = (TextView) view.findViewById(R.id.concert_day_name);
        concertDayNumber = (TextView) view.findViewById(R.id.concert_day_number);
        concertMonthName = (TextView) view.findViewById(R.id.concert_month_name);
        concertOnSaleNow = (TextView) view.findViewById(R.id.concert_on_sale_now);
        concertPlaceName = (TextView) view.findViewById(R.id.concert_place_name);

        for(int i = 0; i < concerts.getAllConcerts().size(); i++) {
            String[] concertRow = concerts.getAllConcerts().get(i);
            concertDayName.setText(concertRow[0]);
            concertDayNumber.setText(concertRow[1]);
            concertMonthName.setText(concertRow[2]);
            concertOnSaleNow.setText(concertRow[3]);
            concertPlaceName.setText(concertRow[4]);
        }
        return view;
    }
}

MenuConcerts.java (This is the fragment that list will be shown)

public class MenuConcerts extends Fragment {

    String[] concertDetails;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.concerts_layout, container, false);

        ((MainActivity) getActivity()).setActionBarTitle(getString(R.string.title_spelningar));

        ListAdapter listAdapter = new CustomerAdapter(getActivity(), concertDetails);

        return view;
    }
}
2
  • 1
    I think a better approach would be to create a Concert class, and instead of private List<String[]> mAllConcerts; you would have private List<Concert> mAllConcerts; Commented May 5, 2015 at 17:11
  • @DanielNugent hi, how should I get all string values from text file into that Concert entity class? Thank you for your comment! Commented May 5, 2015 at 17:14

4 Answers 4

2

I suggest that you do a CustomAdapter with an ArrayList of objects instead of an array of string arrays:

Public Class Concert {
private String dayName;
private String dayNumber;
// constructors, getter and setters
}

So you just do:

   public class CustomAdapterextends BaseAdapter {

Context context;

protected List<Concert> listConcert;
LayoutInflater inflater;

public ListCarsAdapter(Context context, List<Concert> listConcert) {
    this.listConcert= listConcert;
    this.inflater = LayoutInflater.from(context);
    this.context = context;
}

public int getCount() {
    return listConcert.size();
}

public Concert getItem(int position) {
    return listConcert.get(position);
}

public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if (convertView == null) {

        holder = new ViewHolder();
        convertView = this.inflater.inflate(R.layout.concert_row,parent, false);

        holder.concertDayName = (TextView) convertView
                .findViewById(R.id.concert_day_name);
        holder.concertDayNumber= (TextView) convertView
                .findViewById(R.id.concert_day_number);
        holder.concertMonthName = (TextView) convertView
                .findViewById(R.id.concert_month_name);
        holder.concertOnSaleNow = (TextView) convertView
                .findViewById(R.id.concert_on_sale_now);
        holder.concertPlaceName = (TextView) convertView
                .findViewById(R.id.concert_place_name);

        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    Concert concert = listConcert.get(position);
    holder.concertDayName .setText(concert.getDayName());
    holder.concertDayNumber.setText(concert.getDayNumber());
    //etc.
    return convertView;
}

private class ViewHolder {
    TextView concertDayName;
    TextView concertDayNumber;
    Textview concertMonthName;
    Textview concertOnSaleNow;
    Textview concertPlaceName;
}

}

And your activity:

public class MenuConcerts extends Fragment {

ArrayList<Concert> arrayConcert = new ArrayList<Concert>();


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.concerts_layout, container, false);

        ((MainActivity) getActivity()).setActionBarTitle(getString(R.string.title_spelningar));
 // all the reading file logic here;
        ListAdapter listAdapter = new CustomerAdapter(getActivity(), arrayConcert);

        return view;
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

I like your solution but I don't see you are using my Concerts.java class which reads from mytextfile.txt. How should I get those values from text file? Thank you for your answer!
@oxyt from what I think, you should read the file from a method of the activity, not the Concert class, if you still want to add that method to your class, you can. But put the attributes that they have too.
Thank you for your help. I finally made it work! :) I did miss your comment (// all the reading file logic here) in MenuConcerts class before. Just saw it and added a method in that class and it's all good now... Thanks to all of you guyz!
1
  1. Where is your ListView? You dont init it in onCreateView method and you need to set listAdapter to ListView.
  2. In CustomAdapter getView method you don't need to inflate view from xml all times. You must to reuse created view. Check convertView:

    if(convertView ==null){ LayoutInflater inflater = LayoutInflater.from(getContext()); convertView = inflater.inflate(R.layout.concert_row, parent, false); }

  3. For your TextView's in adapter is better to use ViewHilder pattern - Example

  4. You don't need this cycle:

    for(int i = 0; i < concerts.getAllConcerts().size(); i++) {
            String[] concertRow = concerts.getAllConcerts().get(i);}
    

use only String[] concertRow = concerts.getAllConcerts().get(position); and then set your text to text fields, because in getView method only one ListView row is created.

1 Comment

Thank you for your answer... Helped me to understand how bad I am at this :)
1

Firstly you should extends BaseAdapter, not ArrayAdapter. In method getView you can inflate your row.xml layout. And findById all your TextViews.

Here is my sample app with custom adapter.

Comments

0

You have to create a list view in your fragment XML file (I'm assuming the view you inflate is that). Then you assign a ID to it (I'll use R.id.list as an example). Once you got that call (in the onCreateView:

ListView lv = (ListView) view.findViewById(R.id.list);
// set the adapter
lv.setAdapter(listAdapter);

And you should be good.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.