Reputation: 838
I've got following problem:
As you can see on the picture, the CITROEN group header is not above the all Citroen car models, like e.g DACIA. The weird thing is that there is around 20 Car Brands like BMW,AUDI...and every group header is above its children items, but not the CITROEN.
This listview is populated from the html file, which has the following structure:
<optgroup label="BMW">
<option value="225" >BMW X3 3.0si</option>
<option value="226" >BMW X5 3.0d A/T</option>
<option value="227" >BMW X5 4.8i A/T</option>
</optgroup>
<optgroup label="CITROËN">
<option value="67" >CITROËN C1 1.0i</option>
<option value="68" >CITROËN C1 1.4 HDi</option>
<option value="69" >CITROËN C2 1.1i</option>
I'm using custom adapter. Here is the source code of the comparing method:
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
progressDialog.dismiss();
adapter = new ModelsAdaper(CarsList.this, generateData());
/*Should sort the ListView alphabetically*/
adapter.sort(new Comparator<Model>() {
@Override
public int compare(Model lhs, Model rhs) {
return lhs.getTitle().compareTo(rhs.getTitle());
}
});
setListAdapter(adapter);
The generateData() method:
private ArrayList<Model> generateData() {
models = new ArrayList<Model>();
/*This loop adds car brands to the listview*/
for(String s: brands){
models.add(new Model(R.drawable.alfa_romeo_icon_52,s));
}
/*This loop inserts car models into the listview*/
int key;
for(int i = 0; i < hashMap.size(); i++) {
key = hashMap.keyAt(i);
models.add(new Model(hashMap.get(key)));
}
return models;
}
And finally, the Model class
public class Model {
private String title;
private boolean isGroupHeader = false;
private int icon;
/**
* This constructor will be used for creating instance od target_item
* @param title is content of the item
*/
public Model(String title){
this.title = title;
}
/**
* This constructor will be used for group headers
* @param icon is icon of the group
* @param title is name of the group
*/
public Model(int icon, String title){
this.icon = icon;
this.title = title;
isGroupHeader = true;
}
EDIT As requested, here is the HTMLParser class source code. Its constructor is called from CarsList Activity, which extends ListActivity
public class HTMLParser {
private String value;
private InputStream is = null;
private Context context=null;
private org.jsoup.nodes.Document document = null;
SparseArray<String> hashMap = new SparseArray<String>();
private ArrayList<String> modelsList = new ArrayList<String>();
private ArrayList<String> brandsList = new ArrayList<String>();
/**
* Constructor is used to pass instance of CarsList Context to get html asset
* @param context instance of the CarsList activity context
*/
public HTMLParser(Context context) throws IOException {
this.context = context;
is = context.getAssets().open("modely aut.html");
document = Jsoup.parse(is,"UTF-8","http://example.com");
}
/**
* The purpose of this method is to parse car brands from html asset
* @return ArrayList of car brands
*/
public ArrayList<String> parseCarBrands(){
Elements models = document.select("optgroup");
for (Element e: models){
brandsList.add(e.attr("label"));
}
return brandsList;
}
/**
* Method parses all car models from html asset. For IO safety operations, it is recommended to call this method
* after parseCarBrands() method, because parseCarModels() method closes inputStream.
* @return SparseArray consisting of key: carID and value: car model
*/
public SparseArray<String> parseCarModels(){
try {
Elements models = document.select("option");
for (Element e: models){
int res = new Scanner(e.toString()).useDelimiter("\\D+").nextInt();
value = e.html();
modelsList.add(value);
hashMap.put(res,value);
}
} finally {
if(is!=null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return hashMap;
}
}
EDIT 2 Possible source of the problem I have made some tests with the same code, but only in simple java project. It looks like some encoding issue. when using
Elements models2 = doc.select("option");
for (Element e: models2){
int key = Integer.parseInt(e.attr("value"));
String modelName = e.html();
modelsList.add(value);
}
the output from System.out.println(modelName) looks like this:
CITROËN C4 1.6i 16V EP turbo
but when parsing just a brand names using String s = e.attr("label");
the output is as it should be.
Do you have any idea, where the problem can be? I will post other parts of the code, if it will be necessary.
I would like to thank you for all your time and effort you give to my question
Upvotes: 1
Views: 100
Reputation: 838
I've made it, but it's such a stupid thing. I've changed few things in the parseCarModels()
First of all, I've changed the return type to LinkedHashMap<Integer,String>
. Parsing the html now seems to be faster.
Then I've changed the value
variable from String to CharSequence. This allowed me to use Html.fromHtml(e.html)
, so the final code looks like this:
public LinkedHashMap<Integer,String> parseCarModels(){
Elements models = document.select("option");
int key;
CharSequence value;
for(Element e: models){
key = Integer.parseInt(e.attr("value"));
value = Html.fromHtml(e.html());
hashMap.put(key,value.toString());
}
if(is!=null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return hashMap;
}
Thank you for all your help. I really appreciate that. I hope that this code isn't very ineffective
Upvotes: 1