Android 通过更改菜单中的请求URL对JSON数组排序
我目前正在显示一个JSON查询中的项目列表,但希望实现一种通过菜单对结果进行排序的方法。我尝试使用的两个排序参数是按受欢迎程度排序和按平均评级排序。我试图通过更改查询结果的URL来实现这一点,因为api查询具有用于显示基于流行度和平均评级的JSON数据的参数。我尝试过在单击菜单项时实现此购买,但该活动不会填充新结果。URL会更改,但不会显示新结果。任何帮助或暗示都将不胜感激 主要活动:Android 通过更改菜单中的请求URL对JSON数组排序,android,Android,我目前正在显示一个JSON查询中的项目列表,但希望实现一种通过菜单对结果进行排序的方法。我尝试使用的两个排序参数是按受欢迎程度排序和按平均评级排序。我试图通过更改查询结果的URL来实现这一点,因为api查询具有用于显示基于流行度和平均评级的JSON数据的参数。我尝试过在单击菜单项时实现此购买,但该活动不会填充新结果。URL会更改,但不会显示新结果。任何帮助或暗示都将不胜感激 主要活动: public class MainActivity extends AppCompatActivity {
public class MainActivity extends AppCompatActivity {
public static final String TAG = "MainActivity";
//Declare some of the objects we are using.
String SEARCH_TERM = "popularity.desc";
private RecyclerView mRecyclerView;
//GridLayoutManage will allow us to load our items in a grid.
private GridLayoutManager gridLayoutManager;
//Custoj Adapter lets us bind out data from the web server with our recylerview
private MovieAdapter mMovieAdapter;
//Need a list to store the data from the server.
private List<Movie> movieData;
/*
API KEY
https://api.themoviedb.org/3/movie/550?api_key=1f5029b7d824dee72f4d4a156dac90ed
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Reference the RecyclerView
mRecyclerView = findViewById(R.id.recycler_view);
//Reference the list. This needs to be done before setting the adapter to the recycler
//view or the app will think there is an empty list.
movieData = new ArrayList<>();
//To update the list with items, we create a new method to do that.
loadMovieData();
//Create a new grid layout manager in order to display data to a grid.
gridLayoutManager = new GridLayoutManager(this, 3);
mRecyclerView.setLayoutManager(gridLayoutManager);
//Bind the data we receive from the web server to the recyclerview itself.
mMovieAdapter = new MovieAdapter(this, movieData);
//Apply the adapter to the recyclerview.
mRecyclerView.setAdapter(mMovieAdapter);
}
//Tell the new method to get the dat abased on the search term within the url.
private void loadMovieData() {
new FetchMovieTask().execute(SEARCH_TERM);
}
//Inflate the menu
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.sort_by_most_popular:
SEARCH_TERM = "popularity.desc";
loadMovieData();
mMovieAdapter.notifyDataSetChanged();
return true;
case R.id.sort_by_highest_rated:
SEARCH_TERM = "popularity.asc";
loadMovieData();
mMovieAdapter.notifyDataSetChanged();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
//We need to use an AsyncTask to perform the request to get the data. The first argument
//we use a String because this will allow us to pass the url.
public class FetchMovieTask extends AsyncTask<String, Void, Void> {
@Override
protected Void doInBackground(String... strings) {
final String MOVIES_RESULTS = "results";
final String MOVIES_POSTER_IMAGE = "poster_path";
final String MOVIES_TITLE = "title";
final String RELEASE_DATE = "release_date";
final String VOTE_AVERAGE = "vote_average";
final String PLOT = "overview";
//Create the network request to download the JSON data from the url database.
URL moviesUrl = NetworkUtils.buildUrl(SEARCH_TERM);
try {
//The response we get is in the form of JSON.
String jsonMoviesResponse = NetworkUtils.getReponseFromHttpUrl(moviesUrl);
//A new JSON object created from the JSON response.
JSONObject moviesJson = new JSONObject(jsonMoviesResponse);
//Read the movie results array from the JSON object.
JSONArray moviesArray = moviesJson.getJSONArray(MOVIES_RESULTS);
//A loop is created to read the array and add the data we need to a list.
for (int i = 0; i < moviesArray.length(); i++) {
String moviePoster;
String movieTitle;
String movieReleaseDate;
String voteAverage;
String plot;
JSONObject movie = moviesArray.getJSONObject(i);
moviePoster = ("http://image.tmdb.org/t/p/w185/" + movie.getString(MOVIES_POSTER_IMAGE));
movieTitle = movie.getString(MOVIES_TITLE);
movieReleaseDate = movie.getString(RELEASE_DATE);
voteAverage = movie.getString(VOTE_AVERAGE);
plot = movie.getString(PLOT);
Movie data = new Movie(movieTitle, movieReleaseDate, moviePoster, voteAverage, plot);
//Add the data items to our movieData list.
movieData.add(data);
}
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
//This is called when the network request is done. We use this method to tell our
//custom adapter that there is a change in the data list so that it can load new cardview
//widgets in the list.
@Override
protected void onPostExecute(Void aVoid) {
mMovieAdapter.notifyDataSetChanged();
}
}
公共类NetworkUtils{
//These utilities will be used to communicate with the servers.
private static final String TAG = NetworkUtils.class.getSimpleName();
private static final String BASE_URL = "https://api.themoviedb.org/3/discover/movie";
private static final String API_KEY = "1f5029b7d824dee72f4d4a156dac90ed";
//This builds the URL used to talk to movie database.
public static URL buildUrl(String SEARCH_TERM) {
Uri builtUri = Uri.parse(BASE_URL).buildUpon()
.appendQueryParameter("api_key",API_KEY)
.appendQueryParameter("sort_by", SEARCH_TERM)
.build();
URL url = null;
try {
url = new URL(builtUri.toString());
} catch (MalformedURLException e) {
e.printStackTrace();
}
Log.v(TAG, "Built URL " + url);
return url;
}
//This method returns the entire result from the HTTP response.
public static String getReponseFromHttpUrl(URL url) throws IOException {
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
InputStream inputStream = urlConnection.getInputStream();
Scanner scanner = new Scanner(inputStream);
scanner.useDelimiter("\\A");
boolean hasInput = scanner.hasNext();
if (hasInput) {
return scanner.next();
} else {
return null;
}
} finally {
urlConnection.disconnect();
}
}
}如果我是对的,在添加新电影之前,您没有清理电影阵列,因此新获取的项目必须位于该列表的末尾。 在AsyncTask的
onPreExecute()
上,您应该调用movieData.clear();mMovieAdapter.notifyDataSetChanged()代码>
希望有帮助 真是太棒了!我删除了notifyDataSetChanged部分,因为它导致应用程序崩溃,但清除数据有效!在获取数据之前初始化适配器,错误应该消失!
//These utilities will be used to communicate with the servers.
private static final String TAG = NetworkUtils.class.getSimpleName();
private static final String BASE_URL = "https://api.themoviedb.org/3/discover/movie";
private static final String API_KEY = "1f5029b7d824dee72f4d4a156dac90ed";
//This builds the URL used to talk to movie database.
public static URL buildUrl(String SEARCH_TERM) {
Uri builtUri = Uri.parse(BASE_URL).buildUpon()
.appendQueryParameter("api_key",API_KEY)
.appendQueryParameter("sort_by", SEARCH_TERM)
.build();
URL url = null;
try {
url = new URL(builtUri.toString());
} catch (MalformedURLException e) {
e.printStackTrace();
}
Log.v(TAG, "Built URL " + url);
return url;
}
//This method returns the entire result from the HTTP response.
public static String getReponseFromHttpUrl(URL url) throws IOException {
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
InputStream inputStream = urlConnection.getInputStream();
Scanner scanner = new Scanner(inputStream);
scanner.useDelimiter("\\A");
boolean hasInput = scanner.hasNext();
if (hasInput) {
return scanner.next();
} else {
return null;
}
} finally {
urlConnection.disconnect();
}
}