android - json 生成的 listview onClick 只显示最后一项
Posted
技术标签:
【中文标题】android - json 生成的 listview onClick 只显示最后一项【英文标题】:android - json generated listview onClick only shows last item 【发布时间】:2017-10-11 22:56:35 【问题描述】:我有一张地图,它显示来自网络的 json 文件中的标记。 我从同一个文件中创建了一个搜索列表视图。 我想要做的是单击任何结果地图缩放与该结果关联的标记后。 但是现在当我点击任何结果时,它只会放大一个标记,这是我的 json 文件中的最后一项。
这是我的代码:
public class MapAcWithMarker extends FragmentActivity
implements OnMapReadyCallback
static final LatLng TEHRAN = new LatLng(35.697291, 51.392378);
private GoogleMap mMap;
public ArrayList<Locations> locationsList;
public ListView listView;
private View parentView;
public DataAdapter adapter;
ArrayList<Locations> arrayListTemp=new ArrayList<>();
EditText inputSearch;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_recyc);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
final SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
// AsyncTaskGetMarker asyncTaskGetMareker= new AsyncTaskGetMarker();
new AsyncTaskGetMarker().execute();
locationsList = new ArrayList<>();
parentView = findViewById(R.id.parentLayout);
inputSearch = (EditText) findViewById(R.id.inputSearch);
listView = (ListView) findViewById(R.id.listView);
listView.setVisibility(View.INVISIBLE);
inputSearch.setOnKeyListener(new View.OnKeyListener()
@Override
public boolean onKey(View view, int keyCode, KeyEvent keyEvent)
if(keyCode== KeyEvent.KEYCODE_DEL)
listView.setVisibility(View.GONE);
return true;
);
inputSearch.addTextChangedListener(new TextWatcher()
@Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int count)
listView.setVisibility(View.VISIBLE);
if(count==0)
listView.setVisibility(View.INVISIBLE);
String searchString= inputSearch.getText()
.toString().toLowerCase(Locale.getDefault());
int realText= searchString.length();
arrayListTemp.clear();
for (int i =0 ; i <locationsList.size(); i++)
try
String pname= locationsList.get(i).getPname()
.toString();
String bicycleno= locationsList.get(i).getBicycleno()
.toString();
if(realText<=pname.length() && realText<= bicycleno.length())
if (searchString.equalsIgnoreCase(pname.substring(0,
realText)) ||
searchString.equalsIgnoreCase(bicycleno.substring(0, realText))
)
arrayListTemp.add(locationsList.get(i));
else
adapter.notifyDataSetChanged();
catch (Exception e)
e.printStackTrace();
Log.d("@w2w2w2w","arrayListTemp size is "+arrayListTemp.size());
adapter = new DataAdapter(MapAcWithMarker.this, arrayListTemp);
listView.setAdapter(adapter);
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3)
@Override
public void afterTextChanged(Editable arg0)
);
RequestInterface api = JsonClient.getApiService();
/**
* Calling JSON
*/
Call<StopList> call = api.getJSON();
/**
* Enqueue Callback will be call when get response...
*/
call.enqueue(new Callback<StopList>()
@Override
public void onResponse(Call<StopList> call, Response<StopList> response)
//Dismiss Dialog
// dialog.dismiss();
if (response.isSuccessful())
/**
* Got Successfully
*/
locationsList = response.body().getLocations();
/**
* Binding that List to Adapter
*/
adapter = new DataAdapter(MapAcWithMarker.this,
locationsList);
listView.setAdapter(adapter);
else
Toast.makeText(getApplicationContext(), "wrong", Toast.LENGTH_SHORT).show();
@Override
public void onFailure(Call<StopList> call, Throwable t)
Toast.makeText(getApplicationContext(), "wrong", Toast.LENGTH_SHORT).show();
);
@Override
public void onMapReady(GoogleMap googleMap)
mMap = googleMap;
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(TEHRAN, 10));
new AsyncTaskGetMarker().execute();
class AsyncTaskGetMarker extends
AsyncTask<String, String, JSONArray>
@Override
protected void onPreExecute()
super.onPreExecute();
@Override
protected JSONArray doInBackground(String... params)
String json = null;
JSONArray jsonarray = null;
HttpURLConnection conn = null;
BufferedReader reader = null;
try
URL url = new URL("https://api.myjson.com/bins/1879ab.json");
conn = (HttpsURLConnection) url.openConnection();
conn.connect();
InputStream in = new BufferedInputStream(conn.getInputStream());
reader = new BufferedReader
(new InputStreamReader(in));
StringBuilder builder = new StringBuilder();
String line = null;
while((line = reader.readLine()) != null)
builder.append(line);
reader.close();
String response = builder.toString();
JSONObject jsonObject = new JSONObject(response);
jsonarray = jsonObject.getJSONArray("stops");
// jsonarray = new JSONArray(response);
catch (IOException e)
e.printStackTrace();
catch (JSONException e)
e.printStackTrace();
return jsonarray;
protected void onPostExecute(final JSONArray jsonarray)
try
final SparseArray<LatLng> positions =
new SparseArray<>();
mMap.clear();
for (int i = 0; i < jsonarray.length(); i++)
JSONObject obj = jsonarray.getJSONObject(i);
String name = obj.getString("name");
String pname = obj.getString("pname");
String bicycleno = obj.getString("bicycleno");
Double lat = obj.getDouble("lat");
Double lang = obj.getDouble("lang");
final LatLng position = new LatLng(lat, lang);
String title = "name: " + name;
mMap.addMarker(new MarkerOptions()
.position(position).title(title));
positions.put(i, position);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l)
if (positions.get(position) != null)
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(positions.get(position), 15));
);
catch (JSONException e)
e.printStackTrace();
【问题讨论】:
【参考方案1】:在onPostExecute
内你有:
position = new LatLng(lat, lang);
String title = "name: " + name;
mMap.addMarker(new MarkerOptions()
.position(position).title(title));
listView.setOnItemClickListener(new AdapterView.OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l)
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(position,15));
);
所以在position
下,你总是最后调用位置。每个onClick
集合都使用此变量(行内:newLatLngZoom(position,15)
)
为了解决这个问题,仅在本地方法内部创建 position
,您不要在文件顶部声明t need global
LatLng 位置`变量
final LatLng position = new LatLng(lat, lang);
//rest of code as above
编辑:还有这些
lat = obj.getDouble("lat");
lang = obj.getDouble("lang");
仅在 for
内 onPostExecute
的一个循环内将它们保持在本地
Double lat = obj.getDouble("lat");
Double lang = obj.getDouble("lang");
您应该在 MapAcWithMarker
类中删除这些声明(在顶部)
//below to remove
public Double lat;
public Double lang;
public LatLng position;
//these are not used anywhere
public int selectionId= -1;
Marker markers;
下一次编辑:
postExecute 方法的完整代码
protected void onPostExecute(final JSONArray jsonarray)
try
final SparseArray<LatLng> positions = new SparseArray<>();
mMap.clear();
for (int i = 0; i < jsonarray.length(); i++)
JSONObject obj = jsonarray.getJSONObject(i);
String name = obj.getString("name");
String pname = obj.getString("pname");
String bicycleno = obj.getString("bicycleno");
Double lat = obj.getDouble("lat");
Double lang = obj.getDouble("lang");
final LatLng position = new LatLng(lat, lang);
String title = "name: " + name;
mMap.addMarker(new MarkerOptions()
.position(position).title(title));
positions.put(i, position);
// set once, outside for loop
listView.setOnItemClickListener(new AdapterView.OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l)
if(positions.get(position)!=null)
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(positions.get(position),15));
);
catch (JSONException e)
e.printStackTrace();
我已经更仔细地检查了您的代码,但……一团糟。您没有通知适配器有关新数据/json 的信息(即使适配器中的数据与位置、标题等上的解析 json 匹配,您也应该刷新布局)。从 JSON 解析的每个对象也被添加到映射为 Marker
和 mMap.addMarker(...)
方法,但我没有看到任何 mMap.clear();
方法被调用,所以当再次下载 JSON 时,点可能会重复(在上面添加了这一行)
另一个编辑 - 你只在列表中绘制了一个项目,因为你有 onTextChanged
方法
for (int i =0 ; i <locationsList.size(); i++)
...
adapter = new DataAdapter(MapAcWithMarker.this, arrayListTemp);
listView.setAdapter(adapter);
...
适配器的创建应该在for
循环之外完成一次。在循环之后但在启动之前检查 arrayListTemp
有更多项目
for (int i =0 ; i <locationsList.size(); i++)
...
Log.d("@w2w2w2w","arrayListTemp size is "+arrayListTemp.size());
adapter = new DataAdapter(MapAcWithMarker.this, arrayListTemp);
listView.setAdapter(adapter);
很多错误...
【讨论】:
我将 finalLatLng position = new LatLng(lat, lang);
放在 onPostExecute 方法中。但它没有用
使用当前代码编辑您的问题,我们将看到接下来的内容:)
lat = obj.getDouble("lat");
和 lang = obj.getDouble("lang");
仍然是全局声明的,最后的值存储在本地创建的所有不同的 LatLng position
中。两行都应该有Double
“前缀”,只能是“本地”
我删除了全局值并在方法中声明了Double
。
查看我上次的编辑,您认为代码中还有更多工作要做......以上是关于android - json 生成的 listview onClick 只显示最后一项的主要内容,如果未能解决你的问题,请参考以下文章
Android -------- kotlin插件神器Json直接生成javaBean
android - json 生成的 listview onClick 只显示最后一项
如何从 fire-base 为不同的产品风格 Android 生成不同的 json 文件