所以,我有这个相当有趣的问题,我有这个活动持有ListView
。当我按下ListView
时,它会启动另一项活动。一旦我回到那个父母的活动,我按下另一个项目,它崩溃说我需要notifyDatasetChanged
,我不知道应该去哪里,我想,但是,想法?
public class StartEsole extends FragmentActivity implements OnMapReadyCallback, LocationListener {
private GoogleMap mMap;
LocationManager locationManager;
ParseGeoPoint point;
ListView listview;
ArrayList<Details> businessList = new ArrayList<>();
SwipeRefreshLayout mySwipeRefreshLayout;
venueDetail vDetailAdapter;
String userGender;
int userAge;
LocationManager mLocationManager;
/**
* ATTENTION: This was auto-generated to implement the App Indexing API.
* See https://g.co/AppIndexing/AndroidStudio for more information.
*/
private GoogleApiClient client;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.activity_start_esole);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
listview = (ListView) findViewById(R.id.whatsLit);
mySwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swiperefresh);
mySwipeRefreshLayout.setRefreshing(true);
runHot();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
//For The Adbanner-loads ads from admob
AdView adView = (AdView) findViewById(R.id.adView);
AdRequest adRequest = new AdRequest.Builder().build();
adView.loadAd(adRequest);
//FIY userFeed is VenueFeed
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent i = new Intent(getApplicationContext(), userFeed.class);
startActivity(i);
i.putExtra("venueName", businessList.get(position).name);
startActivity(i);
}
});
mySwipeRefreshLayout.setOnRefreshListener(
new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
Log.i("AppInfo", "onRefresh called from SwipeRefreshLayout");
runHot();
}
}
);
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
LatLng home = new LatLng(getLocation().getLatitude(), getLocation().getLongitude());
mMap.setMyLocationEnabled(true);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(home, 18));
}
@Override
public void onLocationChanged(Location curLocation) {
mMap.clear();
mMap.setMyLocationEnabled(true);
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(curLocation.getLatitude(), curLocation.getLongitude()), 18));
Log.i("AppInfo", "Location Changed");
runHot();
listview.setAdapter(vDetailAdapter);
}
@Override
protected void onPause() {
super.onPause();
try {
locationManager.removeUpdates(this);
checkLogic();
} catch (Exception e) {
e.printStackTrace();
e.getCause();
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
public void onBackPressed() {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
@Override
protected void onResume() {
super.onResume();
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1800000,0,this);
mMap.setMyLocationEnabled(true);
mySwipeRefreshLayout.setRefreshing(true);
vDetailAdapter = new venueDetail(StartEsole.this,businessList);
vDetailAdapter.notifyDataSetChanged();
runHot();
}
private void runHot() {
mySwipeRefreshLayout.setRefreshing(true);
aggregateTaskBars taskBars = new aggregateTaskBars();
taskBars.execute();
getLocation();
checkLogic();
}
public Location getLocation() {
mLocationManager = (LocationManager) getApplicationContext().getSystemService(LOCATION_SERVICE);
List<String> providers = mLocationManager.getProviders(true);
Location bestLocation = null;
for (String provider : providers) {
Location l = mLocationManager.getLastKnownLocation(provider);
if (l == null) {
continue;
}
if (bestLocation == null || l.getAccuracy() < bestLocation.getAccuracy()) {
bestLocation = l;
}
}
try {
assert bestLocation != null;
point = new ParseGeoPoint(bestLocation.getLatitude(), bestLocation.getLongitude());
//ParseQuery to update user activity on the serverside.
final ParseObject userActivity = new ParseObject("UserActivity");
ParseQuery<ParseObject> quserActivity = ParseQuery.getQuery("UserActivity");
quserActivity.whereEqualTo("userId", ParseUser.getCurrentUser().getUsername());
quserActivity.findInBackground(new FindCallback<ParseObject>() {
@Override
public void done(List<ParseObject> objects, ParseException e) {
if (e == null) {
if (objects.size() > 0) {
for (ParseObject object : objects) {
object.put("UserLocation", point);
object.saveInBackground();
}
}
if (objects.size() == 0) {
userActivity.put("UserLocation", point);
userActivity.put("userId", ParseUser.getCurrentUser().getUsername());
userActivity.saveInBackground();
}
} else {
e.printStackTrace();
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
return bestLocation;
}
public void checkLogic(){
ParseQuery<ParseObject> qUserActivity = ParseQuery.getQuery("UserActivity");
if(businessList.size()>0){
if(Double.valueOf(businessList.get(0).adistance)<0.00189394){
qUserActivity.whereEqualTo("userId",ParseUser.getCurrentUser().getUsername());
try{
List<ParseObject>qReply = qUserActivity.find();
if(qReply.size()>0){
for(ParseObject object : qReply){
object.put("CurrentHotspot",businessList.get(0).name);
object.put("venueId",businessList.get(0).id);
object.saveInBackground();
}
}
}catch(Exception e){
e.printStackTrace();
}
}else if(Double.valueOf(businessList.get(0).adistance)>0.00189394){
qUserActivity.whereEqualTo("userId",ParseUser.getCurrentUser().getUsername());
try{
List<ParseObject>qReply = qUserActivity.find();
if(qReply.size()>0){
for(ParseObject object : qReply){
object.put("CurrentHotspot","None");
object.put("venueId","empty");
object.saveInBackground();
}
}
}catch(Exception e){
e.printStackTrace();
}
}
}
}
//For Set Map to the hottest place nearby
public void startHeat(View view) {
Log.i("App info", "Started Lit House");
}
//To get the GCD(math) to get a generic ratio between 2 numbers
public int egcd(int a, int b) {
if (a == 0)
return b;
while (b != 0) {
if (a > b)
a = a - b;
else
b = b - a;
}
return a;
}
public String truncateDistance(String x){
Double dTempDist = Double.valueOf(x);
if(dTempDist<1.0){
//
double feet = dTempDist*(5280);
x = "~"+String.valueOf((int)feet) + " ft";
}
else if(dTempDist>1){
x="~"+String.valueOf(dTempDist.intValue()) + " mi";
}
return x;
}
public class aggregateTaskBars extends AsyncTask<String, Void, String> {
ParseGeoPoint myPoint = new ParseGeoPoint(getLocation().getLatitude(), getLocation().getLongitude());
public void downloadLocally() {
downLoadTask nightClubDownload = new downLoadTask();
nightClubDownload.execute("https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=" + String.valueOf(getLocation().getLatitude()) + "," + String.valueOf(getLocation().getLongitude()) + "&rankby=distance" + "&types=" + "night_club" + "&sensor=true" + "&key=A");
downLoadTask barDownload = new downLoadTask();
barDownload.execute("https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=" + String.valueOf(getLocation().getLatitude()) + "," + String.valueOf(getLocation().getLongitude()) + "&rankby=distance" + "&types=" + "bar" + "&sensor=true" + "&key=A");
}
@Override
protected String doInBackground(String... params) {
//Query the user demographic for current user
ParseQuery<ParseObject> userDemo = new ParseQuery<>("UserActivity");
//Log.i("AppInfo",ParseUser.getCurrentUser().getUsername());
userDemo.whereEqualTo("userId", ParseUser.getCurrentUser().getUsername());
try{
List<ParseObject> qReply=userDemo.find();
userAge = qReply.get(0).getInt("Age");
userGender = qReply.get(0).getString("Gender");
}
catch (Exception e){
e.printStackTrace();
}
//Query the bars
ParseQuery<ParseObject> HotSpotBars = new ParseQuery<>("HotSpots");
HotSpotBars.whereWithinMiles("venueLocation", myPoint, 10);
try {
List<ParseObject> qReply = HotSpotBars.find();
if(qReply.size()>10){
for(int i = 0; i<qReply.size();i++){
ParseGeoPoint myloc = new ParseGeoPoint(getLocation().getLatitude(),getLocation().getLongitude());
String sDistance = truncateDistance(String.valueOf(myloc.distanceInMilesTo(qReply.get(i).getParseGeoPoint("venueLocation"))));
String aDistance = String.valueOf(myloc.distanceInMilesTo(qReply.get(i).getParseGeoPoint("venueLocation")));
String venueName = qReply.get(i).getString("venue");
String id = qReply.get(i).getObjectId();
//TODO Create method to count total number of users
int count = queryCount(venueName,id,false,"",false);
String sCount="";
if(count ==0){
sCount=" Dead";}
if(count> 0 && count < 10){
sCount = " Nothing big";
}
if (count>=10 && count < 25){
sCount = " a little something";
}
if(count>=25 && count<50){
sCount = "May b a good one";
}
if(count>=50 && count< 70){
sCount = " Packed";
}
if(count>=70){
sCount = "Its goin to b litt";
}
//TODO Create a method getGenderCount
int genderCountM = queryCount(venueName,id,true,"M",false);
int genderCountF = queryCount(venueName,id,true,"F",false);
int GCD = egcd(genderCountF,genderCountM);
String genderRatio="";
if(GCD == 0){
genderRatio = "Its dead";
}
else if (GCD>0){
genderRatio = String.valueOf(genderCountF/GCD)+" F :"+ String.valueOf(genderCountM/GCD)+" M";
}
Details newVenue = new Details(venueName,"Dist: "+sDistance, aDistance,"ageRange", genderRatio,sCount,count,id);
businessList.add(newVenue);
}
}
else{
//Log.i("AppInfo", "Downloading info... From Google API");
downloadLocally();
}
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
protected int queryCount(String name, String objectID, boolean onGender, String gender,boolean onAge){
int total = 0;
ParseQuery<ParseObject> qUserActivity=new ParseQuery<>("UserActivity");
qUserActivity.whereEqualTo("CurrentHotspot",name);
qUserActivity.whereEqualTo("venueId", objectID);
if(onAge){
//TODO work with breaking down agegroup
}
if(onGender){
qUserActivity.whereEqualTo("Gender", gender);
}
try{
List<ParseObject> qReply = qUserActivity.find();
total = qReply.size();
}catch (Exception e){
e.printStackTrace();
}
//Log.i("AppInfo",String.valueOf(total));
return total;
}
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
mySwipeRefreshLayout.setRefreshing(false);
vDetailAdapter = new venueDetail(StartEsole.this,businessList);
listview.setAdapter(vDetailAdapter);
}
}
我知道每次你添加一些东西......你需要notifyDatasetChanged
,但我不知道应该去哪里。
我用这个作为参考: notifyDataSetChanged example
还没有运气,错误如下:
编辑:请求错误和venueDetail类。
08-27 01:00:54.215 15492-15492/com.esole.esole E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.esole.esole, PID: 15492
java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. Make sure your adapter calls notifyDataSetChanged() when its content changes. [in ListView(2131624124, class android.widget.ListView) with Adapter(class com.esole.esole.venueDetail)]
at android.widget.ListView.layoutChildren(ListView.java:1575)
at android.widget.AbsListView.onTouchUp(AbsListView.java:4069)
at android.widget.AbsListView.onTouchEvent(AbsListView.java:3820)
at android.view.View.dispatchTouchEvent(View.java:9297)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2549)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2240)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2555)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2555)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2555)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2555)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2555)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2555)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254)
at com.android.internal.policy.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2445)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent_aroundBody0(PhoneWindow.java:1756)
at com.android.internal.policy.PhoneWindow$AjcClosure1.run(PhoneWindow.java:1)
at android.view.PhoneWindowAO.ajc$around$android_view_PhoneWindowAO$2$99ce526bproceed(PhoneWindowAO.aj:113)
at android.view.PhoneWindowAO.ajc$around$android_view_PhoneWindowAO$2$99ce526b(PhoneWindowAO.aj:117)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1756)
at android.app.Activity.dispatchTouchEvent(Activity.java:2800)
at com.android.internal.policy.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2406)
at android.view.View.dispatchPointerEvent(View.java:9517)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4309)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4175)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3682)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3735)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3701)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3709)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3682)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3735)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3701)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3828)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3709)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3885)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3682)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3735)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3701)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3709)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3682)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6001)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5975)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5936
场地详情类:
public class venueDetail extends ArrayAdapter<Details> {
public venueDetail(Context context, ArrayList<Details> venues) {
super(context, 0,venues);
}
@Override
public View getView(int position, View convertView, ViewGroup parent ){
Details detail = getItem(position);
if(convertView==null){
convertView= LayoutInflater.from(getContext()).inflate(R.layout.mylayout,parent,false);
}
TextView tvName = (TextView) convertView.findViewById(R.id.venueName);
TextView tvDistance = (TextView) convertView.findViewById(R.id.textDistance);
TextView tvAgeRange = (TextView) convertView.findViewById(R.id.textAgeRange);
TextView tvUserCount = (TextView) convertView.findViewById(R.id.textUserCount);
TextView tvGenderRatio = (TextView) convertView.findViewById(R.id.textGenderRatio);
tvName.setText(detail.name);
tvDistance.setText(detail.sdistance);
tvAgeRange.setText(detail.ageRange);
tvUserCount.setText(detail.sCount);
tvGenderRatio.setText(detail.genderRatio);
//notifyDataSetChanged();
return convertView;
}
}
答案 0 :(得分:0)
我想出了问题,问题是当我运行on resume方法时,它会运行一个请求位置更新,而这又会运行onLocationChanged,这意味着每次GPS位置发生变化时它都会运行任务后台,不断向列表添加项目,这意味着它需要运行notifyDataSetChanged()。我刚刚在这里注释了runhot方法调用
@Override
public void onLocationChanged(Location curLocation) {
mMap.clear();
mMap.setMyLocationEnabled(true);
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(curLocation.getLatitude(), curLocation.getLongitude()), 18));
Log.i("AppInfo", "Location Changed");
//runHot();
listview.setAdapter(vDetailAdapter);
}