java 阳光RecyclerView
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 阳光RecyclerView相关的知识,希望对你有一定的参考价值。
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.sunshine;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.example.android.sunshine.ForecastAdapter.ForecastAdapterOnClickHandler;
import com.example.android.sunshine.data.SunshinePreferences;
import com.example.android.sunshine.utilities.NetworkUtils;
import com.example.android.sunshine.utilities.OpenWeatherJsonUtils;
import java.net.URL;
// COMPLETED (8) Implement ForecastAdapterOnClickHandler from the MainActivity
public class MainActivity extends AppCompatActivity implements ForecastAdapterOnClickHandler {
private RecyclerView mRecyclerView;
private ForecastAdapter mForecastAdapter;
private TextView mErrorMessageDisplay;
private ProgressBar mLoadingIndicator;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_forecast);
/*
* Using findViewById, we get a reference to our RecyclerView from xml. This allows us to
* do things like set the adapter of the RecyclerView and toggle the visibility.
*/
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview_forecast);
/* This TextView is used to display errors and will be hidden if there are no errors */
mErrorMessageDisplay = (TextView) findViewById(R.id.tv_error_message_display);
/*
* LinearLayoutManager can support HORIZONTAL or VERTICAL orientations. The reverse layout
* parameter is useful mostly for HORIZONTAL layouts that should reverse for right to left
* languages.
*/
LinearLayoutManager layoutManager
= new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(layoutManager);
/*
* Use this setting to improve performance if you know that changes in content do not
* change the child layout size in the RecyclerView
*/
mRecyclerView.setHasFixedSize(true);
// COMPLETED (11) Pass in 'this' as the ForecastAdapterOnClickHandler
/*
* The ForecastAdapter is responsible for linking our weather data with the Views that
* will end up displaying our weather data.
*/
mForecastAdapter = new ForecastAdapter(this);
/* Setting the adapter attaches it to the RecyclerView in our layout. */
mRecyclerView.setAdapter(mForecastAdapter);
/*
* The ProgressBar that will indicate to the user that we are loading data. It will be
* hidden when no data is loading.
*
* Please note: This so called "ProgressBar" isn't a bar by default. It is more of a
* circle. We didn't make the rules (or the names of Views), we just follow them.
*/
mLoadingIndicator = (ProgressBar) findViewById(R.id.pb_loading_indicator);
/* Once all of our views are setup, we can load the weather data. */
loadWeatherData();
}
/**
* This method will get the user's preferred location for weather, and then tell some
* background method to get the weather data in the background.
*/
private void loadWeatherData() {
showWeatherDataView();
String location = SunshinePreferences.getPreferredWeatherLocation(this);
new FetchWeatherTask().execute(location);
}
// COMPLETED (9) Override ForecastAdapterOnClickHandler's onClick method
// COMPLETED (10) Show a Toast when an item is clicked, displaying that item's weather data
/**
* This method is overridden by our MainActivity class in order to handle RecyclerView item
* clicks.
*
* @param weatherForDay The weather for the day that was clicked
*/
@Override
public void onClick(String weatherForDay) {
Context context = this;
Toast.makeText(context, weatherForDay, Toast.LENGTH_SHORT)
.show();
}
/**
* This method will make the View for the weather data visible and
* hide the error message.
* <p>
* Since it is okay to redundantly set the visibility of a View, we don't
* need to check whether each view is currently visible or invisible.
*/
private void showWeatherDataView() {
/* First, make sure the error is invisible */
mErrorMessageDisplay.setVisibility(View.INVISIBLE);
/* Then, make sure the weather data is visible */
mRecyclerView.setVisibility(View.VISIBLE);
}
/**
* This method will make the error message visible and hide the weather
* View.
* <p>
* Since it is okay to redundantly set the visibility of a View, we don't
* need to check whether each view is currently visible or invisible.
*/
private void showErrorMessage() {
/* First, hide the currently visible data */
mRecyclerView.setVisibility(View.INVISIBLE);
/* Then, show the error */
mErrorMessageDisplay.setVisibility(View.VISIBLE);
}
public class FetchWeatherTask extends AsyncTask<String, Void, String[]> {
@Override
protected void onPreExecute() {
super.onPreExecute();
mLoadingIndicator.setVisibility(View.VISIBLE);
}
@Override
protected String[] doInBackground(String... params) {
/* If there's no zip code, there's nothing to look up. */
if (params.length == 0) {
return null;
}
String location = params[0];
URL weatherRequestUrl = NetworkUtils.buildUrl(location);
try {
String jsonWeatherResponse = NetworkUtils
.getResponseFromHttpUrl(weatherRequestUrl);
String[] simpleJsonWeatherData = OpenWeatherJsonUtils
.getSimpleWeatherStringsFromJson(MainActivity.this, jsonWeatherResponse);
return simpleJsonWeatherData;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
@Override
protected void onPostExecute(String[] weatherData) {
mLoadingIndicator.setVisibility(View.INVISIBLE);
if (weatherData != null) {
showWeatherDataView();
mForecastAdapter.setWeatherData(weatherData);
} else {
showErrorMessage();
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
/* Use AppCompatActivity's method getMenuInflater to get a handle on the menu inflater */
MenuInflater inflater = getMenuInflater();
/* Use the inflater's inflate method to inflate our menu layout to this menu */
inflater.inflate(R.menu.forecast, menu);
/* Return true so that the menu is displayed in the Toolbar */
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_refresh) {
mForecastAdapter.setWeatherData(null);
loadWeatherData();
return true;
}
return super.onOptionsItemSelected(item);
}
}
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.sunshine;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.TextView;
/**
* {@link ForecastAdapter} exposes a list of weather forecasts to a
* {@link android.support.v7.widget.RecyclerView}
*/
public class ForecastAdapter extends RecyclerView.Adapter<ForecastAdapter.ForecastAdapterViewHolder> {
private String[] mWeatherData;
// COMPLETED (3) Create a final private ForecastAdapterOnClickHandler called mClickHandler
/*
* An on-click handler that we've defined to make it easy for an Activity to interface with
* our RecyclerView
*/
private final ForecastAdapterOnClickHandler mClickHandler;
// COMPLETED (1) Add an interface called ForecastAdapterOnClickHandler
// COMPLETED (2) Within that interface, define a void method that access a String as a parameter
/**
* The interface that receives onClick messages.
*/
public interface ForecastAdapterOnClickHandler {
void onClick(String weatherForDay);
}
// COMPLETED (4) Add a ForecastAdapterOnClickHandler as a parameter to the constructor and store it in mClickHandler
/**
* Creates a ForecastAdapter.
*
* @param clickHandler The on-click handler for this adapter. This single handler is called
* when an item is clicked.
*/
public ForecastAdapter(ForecastAdapterOnClickHandler clickHandler) {
mClickHandler = clickHandler;
}
// COMPLETED (5) Implement OnClickListener in the ForecastAdapterViewHolder class
/**
* Cache of the children views for a forecast list item.
*/
public class ForecastAdapterViewHolder extends RecyclerView.ViewHolder implements OnClickListener {
public final TextView mWeatherTextView;
public ForecastAdapterViewHolder(View view) {
super(view);
mWeatherTextView = (TextView) view.findViewById(R.id.tv_weather_data);
// COMPLETED (7) Call setOnClickListener on the view passed into the constructor (use 'this' as the OnClickListener)
view.setOnClickListener(this);
}
// COMPLETED (6) Override onClick, passing the clicked day's data to mClickHandler via its onClick method
/**
* This gets called by the child views during a click.
*
* @param v The View that was clicked
*/
@Override
public void onClick(View v) {
int adapterPosition = getAdapterPosition();
String weatherForDay = mWeatherData[adapterPosition];
mClickHandler.onClick(weatherForDay);
}
}
/**
* This gets called when each new ViewHolder is created. This happens when the RecyclerView
* is laid out. Enough ViewHolders will be created to fill the screen and allow for scrolling.
*
* @param viewGroup The ViewGroup that these ViewHolders are contained within.
* @param viewType If your RecyclerView has more than one type of item (which ours doesn't) you
* can use this viewType integer to provide a different layout. See
* {@link android.support.v7.widget.RecyclerView.Adapter#getItemViewType(int)}
* for more details.
* @return A new ForecastAdapterViewHolder that holds the View for each list item
*/
@Override
public ForecastAdapterViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
Context context = viewGroup.getContext();
int layoutIdForListItem = R.layout.forecast_list_item;
LayoutInflater inflater = LayoutInflater.from(context);
boolean shouldAttachToParentImmediately = false;
View view = inflater.inflate(layoutIdForListItem, viewGroup, shouldAttachToParentImmediately);
return new ForecastAdapterViewHolder(view);
}
/**
* OnBindViewHolder is called by the RecyclerView to display the data at the specified
* position. In this method, we update the contents of the ViewHolder to display the weather
* details for this particular position, using the "position" argument that is conveniently
* passed into us.
*
* @param forecastAdapterViewHolder The ViewHolder which should be updated to represent the
* contents of the item at the given position in the data set.
* @param position The position of the item within the adapter's data set.
*/
@Override
public void onBindViewHolder(ForecastAdapterViewHolder forecastAdapterViewHolder, int position) {
String weatherForThisDay = mWeatherData[position];
forecastAdapterViewHolder.mWeatherTextView.setText(weatherForThisDay);
}
/**
* This method simply returns the number of items to display. It is used behind the scenes
* to help layout our Views and for animations.
*
* @return The number of items available in our forecast
*/
@Override
public int getItemCount() {
if (null == mWeatherData) return 0;
return mWeatherData.length;
}
/**
* This method is used to set the weather forecast on a ForecastAdapter if we've already
* created one. This is handy when we get new data from the web but don't want to create a
* new ForecastAdapter to display it.
*
* @param weatherData The new weather data to be displayed.
*/
public void setWeatherData(String[] weatherData) {
mWeatherData = weatherData;
notifyDataSetChanged();
}
}
以上是关于java 阳光RecyclerView的主要内容,如果未能解决你的问题,请参考以下文章