简体   繁体   中英

RatingBar in fragment with ListView from Parse data

Basically I have in my Parse database two columns "rank" and "rankCount" which are both numbers.

Rank represents the total rank of the item in that row and rankCount represents the number of people who ranked it.

解析

What I'm trying to do is create a method which will sum the average between those two, make an Int out of the number(in case its a Double/Float) and display the corresponding number with stars in a RatingBar between 1-5 stars, inside a specified Fragment with a ListView in it.

Note: I don't want to make changes in the parse database because I'm using it for the iphone version of this app witch is already complete, but I'm having a more difficult time with android.

specific Fragment class:

public class RecommendedTab extends Fragment {
ListView recommendedListView;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View tab_recommended = inflater.inflate(R.layout.tab_recommended, container, false);
    recommendedListView = (ListView)tab_recommended.findViewById(R.id.recommendedList);

    ParseQuery<ParseObject> query = ParseQuery.getQuery("Place");
    new RemoteDataTask(){
        protected void onPostExecute(List<Places> places) {
            recommendedListView.setAdapter(new PlacesAdapter(getActivity(), places, null));
        }
    }.execute(query);
    return tab_recommended;
   }
}

Adapter class:

public class PlacesAdapter extends BaseAdapter{

private List<Places> places=null;
private List<Places> filteredPlaces=null;
LayoutInflater inflater;
ImageLoader imageLoader;
private Context context;
private Location loc;

public PlacesAdapter(Context context, List<Places> places, Location loc){
    this.context = context;
    this.places = places;
    inflater = LayoutInflater.from(context);
    imageLoader = new ImageLoader(context);
    resetPlaces();
}

public void resetPlaces(){
    filteredPlaces = places;
}

public void filter(String s){
    //validation
    filteredPlaces = new ArrayList<Places>();//
    for(int i=0;i<places.size();i++){
       if(places.get(i).getName().toLowerCase().contains(s.toLowerCase())){
           filteredPlaces.add(places.get(i));
       }
    }
}

public class ViewHolder {
    RatingBar ratingBar;
    TextView name;
    TextView type;
    TextView adress;
    TextView phone;
    TextView hours;
    TextView details;
    ImageView image;
}

@Override
public int getCount() {
    return filteredPlaces.size();
}

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

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

@Override
public View getView(final int position, View view, ViewGroup parent) {
    final ViewHolder holder;
    if (view == null) {
        holder = new ViewHolder();
        view = inflater.inflate(R.layout.row_layout, null);

        holder.name = (TextView)view.findViewById(R.id.placeName);
        holder.type = (TextView) view.findViewById(R.id.placeType);
        holder.image = (ImageView) view.findViewById(R.id.placeImage);
        holder.ratingBar = (RatingBar)view.findViewById(R.id.placeRate);

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

    holder.ratingBar.setOnRatingBarChangeListener(onRatingChangedListener(holder, position));
    holder.ratingBar.setTag(position);
    holder.ratingBar.setRating(places.get(position).getRatingStar());
    holder.name.setText(places.get(position).getName());
    holder.type.setText(places.get(position).getType());

    imageLoader.DisplayImage(places.get(position).getImage(),
            holder.image);

    view.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View arg0) {
            Intent intent = new Intent(context, PlaceDetails.class);
            intent.putExtra("name",  (places.get(position).getName()));
            intent.putExtra("phone",  (places.get(position).getPhone()));
            intent.putExtra("hours", (places.get(position).getHours()));
            intent.putExtra("rank", (places.get(position).getRatingStar()));
            intent.putExtra("details",  (places.get(position).getDetails()));
            intent.putExtra("image", (places.get(position).getImage()));
            context.startActivity(intent);
        }
    });
    return view;
}

private RatingBar.OnRatingBarChangeListener onRatingChangedListener(final ViewHolder holder, final int position) {
    return new RatingBar.OnRatingBarChangeListener() {
        @Override
        public void onRatingChanged(RatingBar ratingBar, float v, boolean b) {
            places.get(position).setRatingStar(v);
        }
    };
  }
}

class for the query:

public class RemoteDataTask extends AsyncTask<ParseQuery<ParseObject>, Void, List<Places>> {
@Override
protected List<Places> doInBackground(ParseQuery<ParseObject>... query) {
    List<Places> places = new ArrayList<Places>();
    try {
        List<ParseObject> ob = query[0].find();
        for (ParseObject place : ob) {
            ParseFile image = (ParseFile) place.get("image");
            Places p = new Places();
            p.setName((String) place.get("name"));
            p.setType((String) place.get("type"));
            p.setHours((String) place.get("hours"));
            p.setPhone((String)place.get("phone"));
            p.setDetails((String) place.get("details"));
            p.setImage(image.getUrl());
            places.add(p);
        }
    } catch (ParseException e) {
        Log.e("Error", e.getMessage());
        e.printStackTrace();
    }
    return places;
    }
}

I have many other classes in my project but im quite sure they are irrelevant for my question.

PS: what is the android equevilant for Swift's "NSUserDefaults"? i need to check if an item already been rated and disable the RatingBar.

There are several ways to do it, for example you can:

  1. Add an instance variable int rank to class Place with needed setter & getter.
  2. Using Math.round set to each Place rank rounded value of rank/rankCount, both you can get with relevant ParseObject.getDouble
  3. And then when creating view for Place, just use it's predefined rank variable as a counter for needed stars.

Note: it's better to use: ParseObject.getString

instead of (String) place.get("name") getting an Object and then casting to String as you did. It's also mentioned in it's Parse Documentation:

In most cases it is more convenient to use a helper function such as ParseObject.getString(String) or ParseObject.getInt(String).

Leave a comment if you need further assistance

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM