Showing list of elements in recyclerView failed - java

I am trying to make a news app, data obtained from RSS feed. I get xml response from the feed. And I am using XmlPullParser to parse the xml. The parsing is a success. I can see the values in my log.
But somehow I am not able to fill them in my recyclerView. It's all just blank. My java class is:
public class RssNewsActivity extends AppCompatActivity {
private static final String TAG = RssNewsActivity.class.toString();
RssFeedAdapter adapter;
RecyclerView recyclerView_rssFeed;
SwipeRefreshLayout swipeRefreshLayout;
private List<RssModel> listResponseModel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rss_news);
initialize();
recyclerView_rssFeed.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
recyclerView_rssFeed.setLayoutManager(linearLayoutManager);
adapter = new RssFeedAdapter(RssNewsActivity.this, listResponseModel);
recyclerView_rssFeed.setAdapter(adapter);
fetchNewsFeed();
//if user swipes the recycler then refresh content page
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
fetchNewsFeed();
}
});
}
private void initialize() {
swipeRefreshLayout = findViewById(R.id.swipeRefresh_rssFeed);
recyclerView_rssFeed = findViewById(R.id.recyclerView_rssFeed);
listResponseModel = new ArrayList<>();
}
private void fetchNewsFeed() {
String url = "here is my news feed url";
StringRequest request = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
listResponseModel.clear();
try {
listResponseModel = parseNewsFeed(response);
} catch (XmlPullParserException | IOException e) {
Log.e(TAG, e.getMessage());
}
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
RequestQueue queue = Volley.newRequestQueue(this);
queue.add(request);
}
private List<RssModel> parseNewsFeed(String response) throws XmlPullParserException,
IOException {
XmlPullParserFactory parserFactory = XmlPullParserFactory.newInstance();
parserFactory.setNamespaceAware(true);
XmlPullParser xmlPullParser = parserFactory.newPullParser();
xmlPullParser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
xmlPullParser.setInput(new StringReader(response));
return processParsing(xmlPullParser);
}
private List<RssModel> processParsing(XmlPullParser xmlPullParser) throws IOException, XmlPullParserException {
List<RssModel> listRssFeed = new ArrayList<>();
int eventType = xmlPullParser.getEventType();
RssModel rssModel = null;
xmlPullParser.nextTag();
while (eventType != XmlPullParser.END_DOCUMENT) {
String eltName;
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
break;
case XmlPullParser.START_TAG:
eltName = xmlPullParser.getName();
if ("item".equals(eltName)) {
rssModel = new RssModel();
} else if (rssModel != null) {
if ("title".equals(eltName)) {
String title = xmlPullParser.nextText();
rssModel.setTitle(title);
Log.d(TAG, "title: " + title);
} else if ("link".equals(eltName)) {
String link = xmlPullParser.nextText();
rssModel.setLink(link);
Log.d(TAG, "link: " + link);
}
}
break;
case XmlPullParser.END_TAG:
eltName = xmlPullParser.getName();
if ("item".equals(eltName) && rssModel != null) {
listRssFeed.add(rssModel);
}
break;
}
eventType = xmlPullParser.next();
}
return listRssFeed;
}
}
my xml design is:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="rssnewsfeed.RssNewsActivity">
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipeRefresh_rssFeed"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView_rssFeed"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>
This is my adapter class
public class RssFeedAdapter extends RecyclerView.Adapter<RssFeedAdapter.RssViewHolder> {
private Context mContext;
private List<RssModel> mRssFeeds;
public RssFeedAdapter(Context mContext, List<RssModel> mRssFeeds) {
this.mContext = mContext;
this.mRssFeeds = mRssFeeds;
}
#NonNull
#Override
public RssViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(mContext).inflate(R.layout.rss_feed_layout, viewGroup, false);
return new RssViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull RssViewHolder rssViewHolder, int i) {
RssModel post = mRssFeeds.get(i);
rssViewHolder.textView_title.setText(post.getTitle());
rssViewHolder.textView_link.setText(post.getLink());
}
#Override
public int getItemCount() {
return mRssFeeds.size();
}
public class RssViewHolder extends RecyclerView.ViewHolder {
private TextView textView_title, textView_link;
public RssViewHolder(#NonNull View itemView) {
super(itemView);
textView_title = itemView.findViewById(R.id.textView_title);
textView_link = itemView.findViewById(R.id.textView_link);
}
}
}
And finally this is my model class:
public class RssModel {
private String title;
private String link;
public RssModel() {
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
}
I tried many ways but no success. I don't know what I am missing. I will be grateful for any guidance. Thanks.

Giving " = " will create a new instance of ArrayList apart from which is already binded to RecyclerView adapter.
So, you need to change this,
listResponseModel = parseNewsFeed(response);
to
listResponseModel.addAll(parseNewsFeed(response));

This happens because the Rss list which you're passing to recycler view adapter is null as you mentioned earlier you're successfully getting the values in log so another guaranteed workaround is to set the values into an separate arraylist.
So inside your class simply create arraylist:
private ArrayList<String> title;
private ArrayList<String> post;
This will be your initialize method:
private void initialize()
{
swipeRefreshLayout = findViewById(R.id.swipeRefresh_rssFeed);
recyclerView_rssFeed = findViewById(R.id.recyclerView_rssFeed);
title = new ArrayList<>();
post = new ArrayList<>();
}
Now simply pass your values to arraylist:
title.add(title)
post.add(post)
Now pass those arraylist to adapter:
adapter = new RssFeedAdapter(RssNewsActivity.this, title,post);
recyclerView_rssFeed.setAdapter(adapter);
After this initialize arraylist in adapter and fetch your values!
One more Important thing inside your oncreate() place your fetchNewsFeed(); method before initializing the adapter
initialize();
fetchNewsFeed();
recyclerView_rssFeed.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
recyclerView_rssFeed.setLayoutManager(linearLayoutManager);
adapter = new RssFeedAdapter(RssNewsActivity.this, listResponseModel);
recyclerView_rssFeed.setAdapter(adapter);

Related

Selecting one from radio group value and scrolling down and some item selected automatically in Recycler View( beginner)

I am making an attendance system where I take the attendance using RadioGroup with two options. When I select some radio button and scroll down some other radio button gets auto-selected. If I change them upper ones also get changed.
Main class
public class TeacherAttendanceActivity extends AppCompatActivity implements AttendanceAdapter.AttendanceAdapterListner {
public static TeacherAttendanceActivity teacherAttendanceActivity;
private static final String TAG = TeacherAttendanceActivity.class.getSimpleName();
List<AttendanceModel> listItems;
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private AttendanceAdapter attendanceAdapter;
ProgressDialog progressDialog;
private SQLiteHandler db;
private SessionManager session;
private SearchView searchView;
Button btnSubmit;
JSONObject mainObj = new JSONObject();
// date
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String currentDateandTime = sdf.format(new Date());
String class_id,title;
Boolean Error;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_teacher_attendance);
//get data from intent
class_id = super.getIntent().getExtras().getString("id"); //class_id
title = super.getIntent().getExtras().getString("title");
getSupportActionBar().setTitle("Class: "+title+", Date: "+currentDateandTime );
// SqLite database handler
db = new SQLiteHandler(getApplicationContext());
// session manager
session = new SessionManager(getApplicationContext());
btnSubmit=findViewById(R.id.buttonAttendanceSubmit);
btnSubmit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Error=false;
Gson gson=new Gson();
final String newDataArray=gson.toJson(listItems); // dataarray is list aaray
for (int i = 0; i < AttendanceAdapter.listItems.size(); i++){
if(AttendanceAdapter.listItems.get(i).getAttendance()==null){
Toast.makeText(TeacherAttendanceActivity.this, "Check attendance at roll:"+AttendanceAdapter.listItems.get(i).getRoll(), Toast.LENGTH_SHORT).show();
Error =true;
break;
}
}
if (!Error){
request(class_id,currentDateandTime,newDataArray);
}
}
});
listItems = new ArrayList<>();
attendanceAdapter = new AttendanceAdapter(listItems, this, (AttendanceAdapter.AttendanceAdapterListner) this);
recyclerView = (RecyclerView) findViewById(R.id.list_attendance);
recyclerView.setLayoutManager(new LinearLayoutManager(TeacherAttendanceActivity.this));
progressDialog = new ProgressDialog(this);
teacherAttendanceActivity = this;
//refresh_list(class_id);
}
#Override
protected void onStart() {
refresh_list(class_id);
super.onStart();
}
#Override
public void onAttendanceAdapterSelected(AttendanceModel model) {
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.refresh, menu);
getMenuInflater().inflate(R.menu.tool_bar, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id){
case R.id.action_settings:
Toast.makeText(getApplicationContext(),"Sittings",Toast.LENGTH_LONG).show();
return true;
case R.id.action_logout:
logoutUser();
return true;
case R.id.action_about:
Toast.makeText(getApplicationContext(),"About",Toast.LENGTH_LONG).show();
return true;
case R.id.action_devinfo:
Toast.makeText(getApplicationContext(),"Dev info",Toast.LENGTH_LONG).show();
return true;
case R.id.refresh:
refresh_list(class_id);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
void logoutUser() {
session.setLogin(false);
db.deleteUsers();
// Launching the login activity
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
}
// refresh list
public void refresh_list(String id) {
// this method refresh list and get the json data
listItems.clear();
// adapter = new MyAdapter(listItems,getApplicationContext());
recyclerView.setAdapter(attendanceAdapter);
recyclerView.setItemAnimator(new DefaultItemAnimator());
progressDialog.setMessage("Loading");
progressDialog.show();
StringRequest stringRequest = new StringRequest(Request.Method.GET, ApiConfig.URL_TEACHER_ATTENDANCE+id, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
progressDialog.dismiss();
try {
progressDialog.hide();
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("Data"); // finding data
Log.d(TAG, String.valueOf(jsonObject));
int len = jsonArray.length();
for (int i = 0; i < len; i++) {
JSONObject o = jsonArray.getJSONObject(i);
AttendanceModel item = new AttendanceModel(
o.getString("id"),
o.getString("name"),
o.getString("roll"),
o.getString("class_id"),
o.getString("status"),
null
);
listItems.add(item);
//adapter = new MyAdapter(listItems,getApplicationContext());
recyclerView.setAdapter(attendanceAdapter); // setting them in list view
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressDialog.hide();
Toast.makeText(TeacherAttendanceActivity.this, "Failed", Toast.LENGTH_SHORT).show();
}
}) {
/** Passing some request headers* */
#Override
public Map getHeaders() throws AuthFailureError {
SQLiteHandler db = new SQLiteHandler(getApplicationContext());
HashMap<String,String> userDetail= db.getUserDetails();
String userToken = userDetail.get("token");
Log.d(TAG, String.valueOf(userToken));
HashMap headers = new HashMap();
headers.put("Accept", "application/json");
headers.put("Authorization", "Bearer "+userToken);
return headers;
}
};
stringRequest.setShouldCache(false);
VolleyRequest.getInstance(TeacherAttendanceActivity.this).addToRequestQueue(stringRequest);
}
// take attendance
private void request( final String classId,final String date,final String data ) {
progressDialog.setMessage("Taking attendance");
showDialog();
StringRequest strReq = new StringRequest(Request.Method.POST,
ApiConfig.URL_TEACHER_ATTENDANCE_STORE, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d(TAG, "Login Response: " + response);
hideDialog();
try {
JSONObject jObj = new JSONObject(response);
boolean error = jObj.getBoolean("error");
// Check for error node in json
if (!error) {
String attendance = jObj.getString("Attendance");
Toast.makeText(TeacherAttendanceActivity.this, attendance, Toast.LENGTH_LONG).show();
finish();
} else {
// Error in login. Get the error message
String errorMsg = jObj.getString("message");
Toast.makeText(TeacherAttendanceActivity.this,
errorMsg, Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
// JSON error
e.printStackTrace();
Toast.makeText(TeacherAttendanceActivity.this, "Json error: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Login Error: " + error.getMessage());
Toast.makeText(TeacherAttendanceActivity.this,
error.getMessage(), Toast.LENGTH_LONG).show();
hideDialog();
}
}) {
/** Passing some request headers* */
#Override
public Map getHeaders() throws AuthFailureError {
SQLiteHandler db = new SQLiteHandler(TeacherAttendanceActivity.this);
HashMap<String,String> userDetail= db.getUserDetails();
String userToken = userDetail.get("token");
Log.d(TAG, String.valueOf(userToken));
HashMap headers = new HashMap();
headers.put("Accept", "application/json");
headers.put("Authorization", "Bearer "+userToken);
return headers;
}
#Override
protected Map<String, String> getParams() {
// Posting parameters to login url
Map<String, String> params = new HashMap<String, String>();
params.put("class_id", classId);
params.put("date", date);
params.put("data", data);
return params;
}
};
strReq.setShouldCache(false);
// Adding request to request queue
VolleyRequest.getInstance(TeacherAttendanceActivity.this).addToRequestQueue(strReq);
}
private void showDialog() {
if (!progressDialog.isShowing())
progressDialog.show();
}
private void hideDialog() {
if (progressDialog.isShowing())
progressDialog.dismiss();
}
}
Model class
'model class for convenient '
public class AttendanceModel {
String id,name,roll,classId,previousAttendance,attendance;
public AttendanceModel(String id, String name,String roll, String classId,String previousAttendance,String attedance ){
this.id = id;
this.name = name;
this.classId =classId;
this.roll=roll;
this.attendance=attedance;
this.previousAttendance=previousAttendance;
}
public String getAttendance() {
return attendance;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public String getRoll() {
return roll;
}
public String getClassId() {
return classId;
}
public String getPreviousAttendance(){return previousAttendance;}
public void setId(String id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setRoll(String roll) {
this.roll = roll;
}
public void setClassId(String classId) {
this.classId = classId;
}
public void setPreviousAttendance(String previousAttendance) {
this.previousAttendance = previousAttendance;
}
public void setAttendance(String attendance) {
this.attendance = attendance;
}
}
Adapter class
' adapter class '
public class AttendanceAdapter extends RecyclerView.Adapter<AttendanceAdapter.ViewHolder> implements Filterable
{
// date
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String currentDateandTime = sdf.format(new Date());
private static final String TAG = AttendanceAdapter.class.getSimpleName();
public static List<AttendanceModel> listItems;
private List<AttendanceModel> listItemsFiltered;
private Context context;
private ProgressDialog dialog;
private AttendanceAdapter.AttendanceAdapterListner listner;
private ProgressDialog pDialog;
private SQLiteHandler db;
public static JSONObject jo = new JSONObject();
public static JSONArray ja = new JSONArray();
public AttendanceAdapter(List<AttendanceModel> listItems, Context context, AttendanceAdapter.AttendanceAdapterListner listner) {
this.listItems = listItems;
this.listner=listner;
this.context = context;
this.listItemsFiltered =listItems;
// SqLite database handler
db = new SQLiteHandler(context);
// Progress dialog
pDialog = new ProgressDialog(context);
}
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString();
if (charString.isEmpty()) {
listItemsFiltered = listItems;
} else {
List<AttendanceModel> filteredList = new ArrayList<>();
for (AttendanceModel row : listItems) {
// name match condition. this might differ depending on your requirement
// here we are looking for name or phone number match
if (row.getName().toUpperCase().contains(charSequence.toString().toUpperCase())||row.getName().toLowerCase().contains(charSequence.toString().toLowerCase())) {
filteredList.add(row);
}
}
listItemsFiltered = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = listItemsFiltered;
return filterResults;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
listItemsFiltered = (ArrayList<AttendanceModel>) filterResults.values;
notifyDataSetChanged();
}
};
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView name;
public TextView roll;
public TextView previous;
RadioGroup radioAttendance;
RadioButton radioAttendancePresent,radioAttendanceAbsent;
public CardView card_view;
public ViewHolder(View itemView) {
super(itemView);
name= (TextView) itemView.findViewById(R.id.textViewAttendanceStudentName);
roll = (TextView) itemView.findViewById(R.id.textViewAttendanceStudentRoll);
previous = (TextView) itemView.findViewById(R.id.textViewAttendanceStudentPreviousStatus);
radioAttendance = itemView.findViewById(R.id.radioAttendance);
radioAttendancePresent =itemView.findViewById(R.id.radioAttendancePresent);
radioAttendanceAbsent =itemView.findViewById(R.id.radioAttendanceAbsent);
//card_view = (CardView) itemView.findViewById(R.id.class_card_view); // card view for on click method
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick( View view) {
// send selected contact in callback
listner.onAttendanceAdapterSelected(listItemsFiltered.get(getAdapterPosition())); // selecting cardview and position (model)
}
});
radioAttendance.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
//Toast.makeText(TeacherAttendanceActivity.this, toString(i), Toast.LENGTH_SHORT).show();
// Toast.makeText(context,"clicked at position"+i+" "+id+""+name,Toast.LENGTH_SHORT).show();
if(radioAttendancePresent.isChecked())
{
listItems.get(getAdapterPosition()).setAttendance("present");
}
else {
listItems.get(getAdapterPosition()).setAttendance("absent");
}
}
});
}
}
#Override
public AttendanceAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.attendance_list, parent, false);
return new AttendanceAdapter.ViewHolder(v);
}
#Override
public void onBindViewHolder (final AttendanceAdapter.ViewHolder holder, final int position) {
final AttendanceModel listItem = listItemsFiltered.get(position);
holder.name.setText(listItem.getName());
holder.roll.setText(listItem.getRoll());
holder.previous.setText(listItem.getPreviousAttendance());
}
public interface AttendanceAdapterListner {
void onAttendanceAdapterSelected(AttendanceModel model); // sending cardview to say the dialoge and model for sending context
}
#Override
public int getItemCount() {
return listItemsFiltered.size();
}
private void showDialog() {
if (!pDialog.isShowing())
pDialog.show();
}
private void hideDialog() {
if (pDialog.isShowing())
pDialog.dismiss();
}
}
Your problem would be solved by making small changes to your Recycler view adapter, please do not disable recyclable property, this makes your recycler view a glorified list view.
I can see you tried using a sparse boolean array to hold the state of the radio buttons, that is good but you do not need that too. The idea behind using a Sparse boolean array is to keep the state of each item in the recycler view so that when they are recycled you still have a reference to what the state of each item is.
In your adapter you already have something that we can use to know the state, that is the attendance property of your model, in that case, you can set the state of your checkboxes by checking if the attendance property is present or absent.
One more thing about your code is that you are using the onCheckChangedListener as a click event handler for your radio button, you should not use this because it responds to all check changed events, even if it is triggered from code and not from user action, so when you bind your view and you set any of your radio buttons as checked or unchecked, it calls this callback.
Here is a modified version of your ViewHolder class that solves this issue by applying the solution above.
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView name;
public TextView roll;
public TextView previous;
RadioGroup radioAttendance;
RadioButton radioAttendancePresent, radioAttendanceAbsent;
public CardView card_view;
public ViewHolder(View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.textViewAttendanceStudentName);
roll = (TextView) itemView.findViewById(R.id.textViewAttendanceStudentRoll);
previous = (TextView) itemView.findViewById(R.id.textViewAttendanceStudentPreviousStatus);
radioAttendance = itemView.findViewById(R.id.radioAttendance);
radioAttendancePresent = itemView.findViewById(R.id.radioAttendancePresent);
radioAttendanceAbsent = itemView.findViewById(R.id.radioAttendanceAbsent);
radioAttendancePresent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
radioAttendancePresent.setChecked(true);
listItems.get(getAdapterPosition()).setAttendance("present");
}
});
radioAttendanceAbsent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
radioAttendanceAbsent.setChecked(true);
listItems.get(getAdapterPosition()).setAttendance("absent");
}
});
}
void bind(int position) {
// use the sparse boolean array to check
if (listItems.get(position).getAttendance() != null) {
if (listItems.get(position).getAttendance().equals("present")) {
radioAttendancePresent.setChecked(true);
} else if (listItems.get(position).getAttendance().equals("absent")) {
radioAttendanceAbsent.setChecked(true);
}
} else {
radioAttendance.clearCheck();
}
name.setText(listItems.get(position).getName());
roll.setText(listItems.get(position).getRoll());
previous.setText(listItems.get(position).getPreviousAttendance());
}
}
Notice that we have separate click listener for each radio button and set the state in the list of items and just check that state when we are binding, also we have removed the onCheckChangedListener and the sparse boolean array, one last thing is that we made sure that when there is not state set for the attendance property, we just clear the radio buttons so that no one is selected the code is much simpler and works correctly now.
You have to initialize your RadioButton based on model state like below:
#Override
public void onBindViewHolder (final AttendanceAdapter.ViewHolder holder, final int position) {
final AttendanceModel listItem = listItemsFiltered.get(position);
holder.name.setText(listItem.getName());
holder.roll.setText(listItem.getRoll());
holder.previous.setText(listItem.getPreviousAttendance());
final String id =listItem.getId();
final String class_id =listItem.getClassId();
holder.radioAttendance.setOnCheckedChangeListener(null);
if(listItem.getAttendance().equalsIgnoreCase("present")) {
radioAttendancePresent.setChecked(true);
} else {
radioAttendancePresent.setChecked(false);
}
//Add listener here and remove from holder
holder.radioAttendance.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
if(holder.radioAttendancePresent.isChecked()) {
listItemsFiltered.get(position).setAttendance("present");
} else {
listItemsFiltered.get(position).setAttendance("absent");
}
notifyDataSetChanged();
}
});
}

Insert data from Google Sheets into Listview

I'm developing an Android app using Google Sheets as a database.
I have information about books in a Google Sheet (title, author, cover, date, etc). I want to retrieve this information and show it in a "Listview" in the "Spreadsheets" Activity. I created a "BookItem" object and an "BookAdapter" adapter. In the "Spreadsheets.java" I have the read method, called "getDataFromApi()". I know that this method works, but I don't know how to adapt it to my "BookAdapter" and show the information on the ListView.
This is mi code:
public class BookItem {
static String title_item;
static Drawable cover_item; //probar con String
public BookItem(String title, Drawable cover){
super();
this.title_item = title;
this.cover_item = cover;
}
public String getTitle() {
return title_item;
}
public void setTitle(String title){
this.title_item = title;
}
public static Drawable getCover() {
return cover_item;
}
public void setCover(Drawable cover) {
this.cover_item = cover;}
This is my BookAdapter:
public class BookAdapter extends BaseAdapter {
private ArrayList<BookItem> items;
List<BookItem> items;
private Context context;
public BookAdapter (Context context, List<BookItem> items) {
this.context = context;
this.items = items;
}
#Override
public int getCount() {
return items.size();
}
#Override
public BookItem getItem(int position) {
return this.items.get(position);
}
#Override
public long getItemId(int i) {
return 0;
}
private static class ViewHolder {
public final ImageView cover_item;
public final TextView title_item;
public ViewHolder (ImageView cover_item, TextView title_item){
this.cover_item = cover_item;
this.title_item = title_item;
}
}
#Override
public View getView (int position, View view, ViewGroup viewGroup) {
ImageView cover_item;
TextView title_item;
if (view == null) {
view = LayoutInflater.from(context).inflate(R.layout.fila_lista_miestanteria, viewGroup, false); //se mete aqui en getView por ser baseAdapter
title_item = (TextView) view.findViewById(R.id.book_title_item);
cover_item = (ImageView) view.findViewById(R.id.book_cover_item);
view.setTag(R.id.book_title_item, title_item);
view.setTag(R.id.book_cover_item, cover_item);
}
else {
cover_item = (ImageView) view.getTag(R.id.book_cover_item);
title_item = (TextView)view.getTag(R.id.book_title_item);
}
BookItem bookItem = getItem(position);
cover_item.setImageDrawable(bookItem.getCover());
title_item.setText(bookItem.getTitle());
return view;
}
}
public class Spreadsheets extends Activity {
static String book_title, book_author, book_date, book_category, book_description, book_rating, book_cover;
static String read_only = "no";
static String book_favorite = "no";
static GoogleAccountCredential mCredential;
private ListView bookList;
private TextView mOutputText;
ProgressDialog mProgress;
Context context;
List<String> rst;
List<BookItem> resultados;
BookAdapter adapter;
private static final String[] SCOPES = {SheetsScopes.SPREADSHEETS};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.spread);
// mOutputText = (TextView) findViewById(R.id.outputText);
bookList = (ListView) findViewById(R.id.bookList);
// mOutputText.setText("");
mProgress = new ProgressDialog(this);
mProgress.setMessage("Calling Google Sheets...");
// Initialize credentials and service object.
mCredential = GoogleAccountCredential.usingOAuth2(
getApplicationContext(), Arrays.asList(SCOPES))
.setBackOff(new ExponentialBackOff());
System.out.print("read only es igual a "+ read_only);
new MakeRequestTask(mCredential).execute();
}
public void rellenar(){
System.out.println("VOY A HACER NEW BOOK ADAPTER ");
adapter = new BookAdapter(context, resultados);
bookList.setAdapter(adapter);
System.out.println("SETADAPTER");
}
private class MakeRequestTask extends AsyncTask<Void, Void, List<String>> {
private Exception mLastError = null;
MakeRequestTask(GoogleAccountCredential credential) {
}
#Override
protected List<String> doInBackground(Void... params) {
try {
if(read_only.equals("no")) {
setDataToApi();
return null;
}
else {
return getDataFromApi();
}
} catch (Exception e) {
mLastError = e;
cancel(true);
return null;
}
}
private List<String> getDataFromApi() throws IOException {
String range = "Sheet1!A1:H";
List<String> results = new ArrayList<String>();
ValueRange response = CreateSpreadsheets.mService.spreadsheets().values()
.get(CreateSpreadsheets.spreadsheet_id, range)
.execute();
List<List<Object>> values = response.getValues();
if (values != null) {
for (List row : values) {
results.add(row.get(0) + ", " + row.get(7));
}
}
//funcion();
return results;
}
private void setDataToApi() throws IOException {
String range = "Sheet1!A2:H";
List<List<Object>> values = new ArrayList<>();
List<Object> data1 = new ArrayList<>();
data1.add(book_title);
data1.add(book_author);
data1.add(book_date);
data1.add(book_category);
data1.add(book_description);
data1.add(book_rating);
data1.add(book_cover);
data1.add("a");
values.add(data1);
ValueRange valueRange = new ValueRange();
valueRange.setMajorDimension("ROWS");
valueRange.setRange(range);
valueRange.setValues(values);
ValueRange body = new ValueRange().setValues(values);
AppendValuesResponse response =
CreateSpreadsheets.mService.spreadsheets().values().append(CreateSpreadsheets.spreadsheet_id, range, body)
.setValueInputOption("RAW")
.execute();
}
#Override
protected void onPreExecute() {
//mOutputText.setText("");
mProgress.show();
}
#Override
protected void onPostExecute(List<String> output) {
mProgress.hide();
if (output == null || output.size() == 0) {
// mOutputText.setText("No results returned.");
} else {
if(read_only.equals("no")) {
Intent intent = new Intent(Spreadsheets.this, MainActivity.class);
startActivity(intent);
// mOutputText.setText("Se ha añadido un libro a su lista");
}
else {
System.out.println("VOY A RELLENAR LA LISTA");
rellenar();
}
}
}
#Override
protected void onCancelled() {
}
}
}
The "spread.xml" is a list, and the "fila_list_miestanteria.xml" is a TextView&ImageView to show the book info.
Thank you so much!

Recyclerview not working properly

I have created a program following all the steps that I found online. What it does is if I have a connection it sends a data to remote server and server responses OK if data entry is successful. My app works fine on saving data to the server side but it does not display on my recyclerview. But when I switch to airplane mode and try to send data to server, It displays on recyclerview that it failed but when it succeeds, it does not show up on recyclerview. Maybe you guys can help. I can't seem to find the error.
Main activity
public class SMSActivity extends AppCompatActivity {
RecyclerView smsRecyclerview;
EditText Smsplace;
RecyclerView.LayoutManager smsLayoutmanager;
SMSAdapter smsAdapter;
ArrayList<SMS> arrayList = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sms);
smsRecyclerview = (RecyclerView)findViewById(R.id.smsRecyclerView);
Smsplace = (EditText)findViewById(R.id.smsplace);
smsLayoutmanager = new LinearLayoutManager(this);
smsRecyclerview.setLayoutManager(smsLayoutmanager);
smsRecyclerview.setHasFixedSize(true);
smsAdapter = new SMSAdapter(arrayList);
smsRecyclerview.setAdapter(smsAdapter);
readFromLocalStorage();
}
public void submitPlace(View view)
{
String smsplace = Smsplace.getText().toString();
saveToAppServer(smsplace);
Smsplace.setText("");
}
private void readFromLocalStorage()
{
arrayList.clear();
SMSHelper smsHelper = new SMSHelper(this);
SQLiteDatabase database = smsHelper.getReadableDatabase();
Cursor cursor = smsHelper.readFromLocalDatabase(database);
while (cursor.moveToNext())
{
String smsplace = cursor.getString(cursor.getColumnIndex(SMSContract.SMSPLACE));
int smssync_status = cursor.getInt(cursor.getColumnIndex(SMSContract.SMSSYNC_STATUS));
arrayList.add(new SMS(smsplace,smssync_status));
}
smsAdapter.notifyDataSetChanged();
cursor.close();
}
private void saveToAppServer(final String smsplace)
{
if(checkNetworkConnection())
{
StringRequest stringRequest = new StringRequest(Request.Method.POST, SMSContract.SERVER_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
String Response = jsonObject.getString("response");
if(Response.equals("OK"))
{
saveToLocalStorage(smsplace,SMSContract.SMSSYNC_STATUS_OK);
}
else
{
saveToLocalStorage(smsplace,SMSContract.SMSSYNC_STATUS_FAILED);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
saveToLocalStorage(smsplace,SMSContract.SMSSYNC_STATUS_FAILED);
}
})
{
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> params = new HashMap<>();
params.put("smsplace",smsplace);
return params;
}
}
;
SMSSingleton.getInstance(SMSActivity.this).addToRequestQue(stringRequest);
}
else
{
saveToLocalStorage(smsplace,SMSContract.SMSSYNC_STATUS_FAILED);
}
}
public boolean checkNetworkConnection()
{
ConnectivityManager connectivityManager = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
return (networkInfo != null && networkInfo.isConnected());
}
private void saveToLocalStorage(String smsplace,int smssync)
{
SMSHelper smsHelper = new SMSHelper(this);
SQLiteDatabase database = smsHelper.getWritableDatabase();
smsHelper.saveToLocalDatabase(smsplace,smssync,database);
readFromLocalStorage();
}
}
RecyclerAdapter
public class SMSAdapter extends RecyclerView.Adapter<SMSAdapter.MyViewHolder> {
private ArrayList<SMS> arrayList = new ArrayList<>();
public SMSAdapter(ArrayList<SMS> arrayList)
{
this.arrayList = arrayList;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.smsitem_view,parent,false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.Smsplace.setText(arrayList.get(position).getSmsplace());
int smssync_status = arrayList.get(position).getSmsSync_status();
if(smssync_status == SMSContract.SMSSYNC_STATUS_OK)
{
holder.Smssync_status.setImageResource(R.drawable.ok);
}
else
{
holder.Smssync_status.setImageResource(R.drawable.sync);
}
}
#Override
public int getItemCount() {
return arrayList.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder
{
ImageView Smssync_status;
TextView Smsplace;
public MyViewHolder(View itemView) {
super(itemView);
Smssync_status = (ImageView)itemView.findViewById(R.id.smsImgsync);
Smsplace = (TextView)itemView.findViewById(R.id.txtSmsplace);
}
}
}
***P.S. I didn't include the sqlitedatabase codes. But if you guys need it. I'd be happy to.

I am using a git repo called LikeButton, but the state of my button keeps jumping around in my recyclerview?

I am using a git repo called LikeButton, but the state of my button keeps jumping around in my recyclerview? Here is the repo https://github.com/jd-alexander/LikeButton. Basically when I click on a recyclerview item, it sets a textview to the word true or false based on if the user liked the post or not, and this works. However, the state of my button is doing some weird stuff, it jumps around...
Here is my Adapter, is their anything wrong with it?
public class ViewpagerAdapter extends RecyclerView.Adapter<ViewpagerAdapter.ViewDashboard>{
private LayoutInflater mLayoutInflater;
private ArrayList<QuestionData> data = new ArrayList<>();
public ViewpagerAdapter(Context context) {
mLayoutInflater=LayoutInflater.from(context);
}
public void setBloglist(ArrayList<QuestionData> listBlogs) {
this.data = listBlogs;
notifyItemRangeChanged(0,listBlogs.size());
}
#Override
public ViewDashboard onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mLayoutInflater.inflate(R.layout.customizejson, parent, false);
ViewDashboard viewholder = new ViewDashboard(view);
return viewholder;
}
#Override
public void onBindViewHolder(ViewDashboard holder, int position) {
QuestionData questionHolder = data.get(position);
holder.questionText.setText(questionHolder.getMtext());
//This sets the text, to a true or a false String
holder.mStudentVoted.setText(questionHolder.getVoters());
holder.mLikeButton.setTag(holder);
}
#Override
public int getItemCount() {
return data.size();
}
class ViewDashboard extends RecyclerView.ViewHolder {
private TextView questionText;
private LikeButton mLikeButton;
private TextView mStudentVoted;
public ViewDashboard(View itemView) {
super(itemView);
questionText = (TextView)itemView.findViewById(R.id.questionText);
mStudentVoted = (TextView)itemView.findViewById(R.id.studentVoted);
mLikeButton = (LikeButton)itemView.findViewById(R.id.like_button_viewpager);
mLikeButton.setOnLikeListener(new OnLikeListener() {
#Override
public void liked(LikeButton likeButton) {
Voting voting = new Voting(getAdapterPosition(),ViewpagerAdapter.this, questionId);
voting.onUpVote();
}
#Override
public void unLiked(LikeButton likeButton) {
Voting voting = new Voting(getAdapterPosition(),ViewpagerAdapter.this, questionId);
voting.onDownVote();
}
});
}
}
}
Voting Class
public class Voting {
private int adapterPosition;
private RecyclerView.Adapter adapter;
private String stringId;
private TextView studentVoted;
//TODO Trim Constructor
public Voting(int adapterPosition,final RecyclerView.Adapter adapter, TextView questionId, TextView studentVoted) {
stringId = questionId.getText().toString();
this.adapter = adapter;
this.studentVoted=studentVoted;
}
public void onUpVote() {
final RequestQueue mRequestQueue = VolleySingleton.getInstance().getRequestQueue();
StringRequest postVoteUp = new StringRequest(Request.Method.PUT, PUT_VOTE_UP, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
System.out.println("Succesful Upvote The Students Value is " + studentVoted);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
System.out.println("failed Upvote");
}
});
mRequestQueue.add(postVoteUp);
}
public void onDownVote() {
final RequestQueue mrequestQueue = VolleySingleton.getInstance().getRequestQueue();
//TODO Delete Token(inserted for student 3 for testing purposes)
StringRequest postVoteDown = new StringRequest(Request.Method.PUT, PUT_VOTE_DOWN, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
//TODO OnResponse, must setLiked(False)
//Succesful downVote The Students Value is true
//studentVoted.setText("false");
System.out.println("Succesful downVote The Students Value is "+studentVoted);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
System.out.println("failed downVote");
}
});
mrequestQueue.add(postVoteDown);
}
public void realTimeUpVoting(TextView textView){
String voteString= textView.getText().toString();
int voteNumber=Integer.parseInt(voteString)+1;
textView.setText("" + voteNumber);
}
public void realTimeDownVoting(TextView textView){
String voteString= textView.getText().toString();
int voteNumber=Integer.parseInt(voteString)-1;
textView.setText("" + voteNumber);
}
}
Json Request and Parsing Methods
public void JsonRequestMethod() {
mVolleySingleton = VolleySingleton.getInstance();
mRequestQueue = mVolleySingleton.getRequestQueue();
JsonArrayRequest request = new JsonArrayRequest(Request.Method.GET, URL_HOME, (String) null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
try {
mListblogs.clear();
mListblogs = new YourTask().execute(response).get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
mRequestQueue.add(request);
}
private ArrayList<QuestionData> parseJSONResponse(JSONArray response) {
if (!response.equals("")) {
try {
StringBuilder data = new StringBuilder();
for (int x = 0; x < response.length(); x++) {
JSONObject currentQuestions = response.getJSONObject(x);
JSONArray arrSubcategory = currentQuestions.optJSONArray("questions");
for (int y = 0; y < arrSubcategory.length(); y++) {
JSONObject objectSubcategory = arrSubcategory.getJSONObject(y);
String text = objectSubcategory.optString("text");
String studentId = objectSubcategory.optString("studentId");
String votes=objectSubcategory.optString("votes");
/*JSONArray cycles through the array of voters, when a user votes
their ID is added to the array.When they downvote, it is removed
*/
JSONArray voters= objectSubcategory.optJSONArray("voters");
QuestionData questionData = new QuestionData();
questionData.setMstudentId(studentId);
questionData.setMtext(text);
questionData.setVotes(votes);
questionData.setVoters(checkIfVoted(voters));
mQuestionDataArrayList.add(questionData);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
return mQuestionDataArrayList;
}
private static String checkIfVoted(JSONArray jsonArray ) {
/*pass in a json Array, copy the array into ints, and if
the students Id is contained in the array return the string true
*/
int[] voteIds = new int[jsonArray.length()];
for(int i=0;i<voteIds.length;i++){
voteIds[i] = jsonArray.optInt(i);
}
for(int i=0;i<voteIds.length;i++){
if(voteIds[i]== Integer.parseInt(Login.getUserId())){
//TODO String was only used for Testing purposes, Convert to Boolean later
return "true";
}
}
return "false";
}
you are currently only updating the textview which is why your recycleview changes state when scrolling.
Should change your voting class and pass the question Data rather textview
public Voting(int adapterPosition,final RecyclerView.Adapter adapter, TextView questionId, TextView studentVoted) {
change to
public Voting(int adapterPosition,final RecyclerView.Adapter adapter, QuestionData questionData, TextView studentVoted) {
// make other changes for the data
and then in
public void realTimeUpVoting(QuestionData questionData){
data.votes++ //something like that. idont know your model
// now call back using interface the recyleview data changed method so it updates the count in recycleview automatically.
Edit
passing the question Data in click button
class ViewDashboard extends RecyclerView.ViewHolder {
public int position
public void onBindViewHolder(ViewDashboard holder, int position) {
holder.position = position
}
public void liked(LikeButton likeButton) {
QuestionData questionHolder = data.get(position);

Android YouTubeSupportFragment player returning null

I have been working on a personal Android project related to YouTube based off a demo, however I have ran into an issue that I can't seem to figure out (or understand).
The original code uses a basic PlayerView whereas this uses a YouTubePlayerSupportFragment.
The app plays videos just fine as long as player.cueVideo("VIDEOID") is inside onInitializationSuccess. But will crash with a NullPointerException on player variable if placed inside the method playVideoAtSelection.
** The original code had the following line inside onInitializationSuccess, however for me it's telling me that player cannot be resolved. **
I've never seen this used like this before so it has been throwing me off.
this.player = player;
MainActivity.java code:
public class MainActivity extends FragmentActivity implements
AdapterView.OnItemClickListener,
AdapterView.OnItemSelectedListener {
private final String LOG_TAG = MainActivity.class.getSimpleName();
AutoCompleteTextView atvSearch;
public String thumbnailURL;
public String mediaTitle;
public String videoID;
private TextView autoItem;
private ImageView autoImage;
private ArrayList<ArrayList<String>> resultList;
private static final String KEY_CURRENTLY_SELECTED_ID = "currentlySelectedId";
private YouTubePlayer mPlayer;
private YouTubePlayer player = null;
private ArrayAdapter<ListEntry> videoAdapter;
private Spinner videoChooser;
private MyPlayerStateChangeListener playerStateChangeListener;
private int currentlySelectedPosition;
private String currentlySelectedId;
private static final ListEntry[] ENTRIES = {
new ListEntry("Androidify App", "irH3OSOskcE", false),
new ListEntry("Chrome Speed Tests", "nCgQDjiotG0", false),
new ListEntry("Playlist: Google I/O 2012", "PL56D792A831D0C362", true)};
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.v(LOG_TAG, "IN onCreate!");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_playlist, new PlaylistFragment())
.commit();
}
//YouTubePlayerFragment playerFragment = YouTubePlayerFragment.newInstance("irH3OSOskcE");
//getSupportFragmentManager().beginTransaction().replace(R.id.youtube_fragment, playerFragment).commit();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
YouTubePlayerSupportFragment youTubePlayerFragment = new YouTubePlayerSupportFragment();
fragmentTransaction.add(R.id.youtube_fragment, youTubePlayerFragment);
fragmentTransaction.commit();
youTubePlayerFragment.initialize(DeveloperKey.DEVELOPER_KEY, new OnInitializedListener() {
#Override
public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer player, boolean wasRestored) {
mPlayer = player;
mPlayer.setPlayerStateChangeListener(playerStateChangeListener);
mPlayer.setPlayerStyle(YouTubePlayer.PlayerStyle.MINIMAL);
if (!wasRestored) {
playVideoAtSelection();
}
}
#Override
public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult youTubeInitializationResult) {
//error
}
});
AutoCompleteTextView autoCompView = (AutoCompleteTextView) findViewById(R.id.atv_search);
autoCompView.setAdapter(new QueryAutoCompleteAdapter(this, R.layout.list_item));
autoCompView.setOnItemClickListener(this);
playerStateChangeListener = new MyPlayerStateChangeListener();
videoChooser = (Spinner) findViewById(R.id.video_chooser);
videoAdapter = new ArrayAdapter<ListEntry>(this, android.R.layout.simple_spinner_item, ENTRIES);
videoAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
videoChooser.setOnItemSelectedListener(this);
videoChooser.setAdapter(videoAdapter);
}
public void playVideoAtSelection() {
if (mPlayer == null) {
Log.v(LOG_TAG, "WE DUN GOOFD PLAYER IS NULL... ");
}
player.cueVideo("nCgQDjiotG0");
Log.v(LOG_TAG, "WE HAVE ENTERED PLAYVIDEOATSELECTION... ");
/*ListEntry selectedEntry = videoAdapter.getItem(currentlySelectedPosition);
if (selectedEntry.id != currentlySelectedId && player != null) {
currentlySelectedId = selectedEntry.id;
if (selectedEntry.isPlaylist) {
player.cuePlaylist(selectedEntry.id);
} else {
player.cueVideo(selectedEntry.id);
}
}*/
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
currentlySelectedPosition = pos;
playVideoAtSelection();
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
// Do nothing.
}
#Override
protected void onSaveInstanceState(Bundle state) {
super.onSaveInstanceState(state);
state.putString(KEY_CURRENTLY_SELECTED_ID, currentlySelectedId);
}
#Override
protected void onRestoreInstanceState(Bundle state) {
super.onRestoreInstanceState(state);
currentlySelectedId = state.getString(KEY_CURRENTLY_SELECTED_ID);
}
private final class MyPlayerStateChangeListener implements YouTubePlayer.PlayerStateChangeListener {
String playerState = "UNINITIALIZED";
#Override
public void onLoading() {
playerState = "LOADING";
}
#Override
public void onLoaded(String videoId) {
playerState = String.format("LOADED %s", videoId);
}
#Override
public void onAdStarted() {
playerState = "AD_STARTED";
}
#Override
public void onVideoStarted() {
playerState = "VIDEO_STARTED";
}
#Override
public void onVideoEnded() {
playerState = "VIDEO_ENDED";
}
#Override
public void onError(YouTubePlayer.ErrorReason reason) {
playerState = "ERROR (" + reason + ")";
if (reason == YouTubePlayer.ErrorReason.UNEXPECTED_SERVICE_DISCONNECTION) {
// When this error occurs the player is released and can no longer be used.
player = null;
//setControlsEnabled(false);
}
}
}
private static final class ListEntry {
public final String title;
public final String id;
public final boolean isPlaylist;
public ListEntry(String title, String videoId, boolean isPlaylist) {
this.title = title;
this.id = videoId;
this.isPlaylist = isPlaylist;
}
#Override
public String toString() {
return title;
}
}
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
String str = (String) adapterView.getItemAtPosition(position);
Toast.makeText(this, str, Toast.LENGTH_SHORT).show();
}
public class QueryAutoCompleteAdapter extends ArrayAdapter<String> implements Filterable {
public QueryAutoCompleteAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
}
#Override
public int getCount() {
return resultList.size();
}
#Override
public String getItem(int index) {
return resultList.get(index).toString();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
LayoutInflater inflater = LayoutInflater.from(getContext());
if (row == null) {
row = inflater.inflate(R.layout.list_item_query, parent, false);
}
ArrayList<String> text = resultList.get(position);
String title = text.get(2);
String url = text.get(1);
videoID = text.get(0);
Log.v(LOG_TAG, "YOOOOOO BAIIII: " + title + url);
autoItem = (TextView) row.findViewById(R.id.list_item_title);
autoImage = (ImageView) row.findViewById(R.id.list_item_thumbnail);
autoItem.setText(title);
Bitmap bm = null;
try {
InputStream in = new java.net.URL(url).openStream();
bm = BitmapFactory.decodeStream(in);
} catch (Exception e) {
//Log.e("ERROR", e.getMessage());
e.printStackTrace();
}
autoImage.setImageBitmap(bm);
return row;
}
#Override
public Filter getFilter() {
Filter filter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
// Constraint is the input given by the user
if (constraint != null) {
// Retrieve the autocomplete results.
resultList = autocomplete(constraint.toString());
int size = resultList.size();
for (int i=0; i<size; i++) {
//temp = resultList.get(i);
Log.v(LOG_TAG, "YOOOOOO: " + resultList.get(i));
thumbnailURL = resultList.get(i).get(1);
mediaTitle = resultList.get(i).get(2);
}
Log.v(LOG_TAG, "YOOOOOO: " + thumbnailURL + " " + mediaTitle);
// Assign the data to the FilterResults
filterResults.values = resultList;
filterResults.count = resultList.size();
}
return filterResults;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results != null && results.count > 0) {
notifyDataSetChanged();
}
else {
notifyDataSetInvalidated();
}
}};
return filter;
}
}
private ArrayList<ArrayList<String>> autocomplete(String input) {
ArrayList<ArrayList<String>> queries = null;
// If there's no query, there is nothing to look up
if (input.length() == 0) {
return null;
}
String songQuery = input;
// These two need to be declared outside the try/catch
// so that they can be closed in the finally block.
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
// Will contain the raw JSON response as a string.
String queryJsonStr = null;
String part = "id,snippet";
String order = "relevance";
String q = songQuery;
String type = "video";
String categoryID = "kind";
String key = DeveloperKey.DEVELOPER_KEY;
try {
// Construct the URL for the query
final String BASE_URL = "https://www.googleapis.com/youtube/v3/search?";
final String PART_PARAM = "part";
final String ORDER_PARAM = "order";
final String QUERY_PARAM = "q";
final String TYPE_PARAM = "type";
final String CATEGORYID_PARAM = "videoCategoryId";
final String KEY_PARAM = "key";
Uri builtUri = Uri.parse(BASE_URL).buildUpon()
.appendQueryParameter(PART_PARAM, part)
.appendQueryParameter(ORDER_PARAM, order)
.appendQueryParameter(QUERY_PARAM, q)
.appendQueryParameter(TYPE_PARAM, type)
.appendQueryParameter(CATEGORYID_PARAM, categoryID)
.appendQueryParameter(KEY_PARAM, key)
.build();
URL url = new URL(builtUri.toString());
Log.v(LOG_TAG, "BUILT URI: " + builtUri.toString());
// Create the request to YouTube, and open the connection
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// Read the input stream into a String
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
// Nothing to do.
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
// Since it's JSON, adding a newline isn't necessary (it won't affect parsing)
// But it does make debugging a *lot* easier if you print out the completed
// buffer for debugging.
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
return null;
}
queryJsonStr = buffer.toString();
Log.v(LOG_TAG, "Query JSON String: " + queryJsonStr);
} catch (IOException e) {
Log.e(LOG_TAG, "ERROR ", e);
// If the code didn't successfully get the weather data, there's no point in attempting
// to parse it.
return null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e("PlaceholderFragment", "Error closing stream", e);
}
}
}
try {
JSONObject jsonObject = new JSONObject(queryJsonStr);
QueryJSONParser queryJSONParser = new QueryJSONParser();
// Getting the parsed data as a list construct
queries = queryJSONParser.parse(jsonObject);
} catch (Exception e) {
Log.d("Exception", e.toString());
}
return queries;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Relevant XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<fragment
android:name="com.google.android.youtube.player.YouTubePlayerSupportFragment"
android:id="#+id/youtube_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:orientation="horizontal"
android:gravity="top">
<include
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
layout="#layout/player_controls_container" />
</LinearLayout>
Any help would be greatly appreciated!
LOGCAT:
08-08 19:52:23.404 6040-6040/com.android.youtube V/MainActivity﹕ WE DUN GOOFD PLAYER IS NULL...
08-08 19:52:23.404 6040-6040/com.android.youtube D/AndroidRuntime﹕ Shutting down VM
08-08 19:52:23.404 6040-6040/com.android.youtube W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x41894da0)
08-08 19:52:23.414 6040-6040/com.android.youtube E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.android.youtube, PID: 6040
java.lang.NullPointerException
at com.android.youtube.MainActivity.playVideoAtSelection(MainActivity.java:132)
at com.android.youtube.MainActivity.onItemSelected(MainActivity.java:148)
You are getting NullPointerException because your player variable is not initialized. You have commented this line:
this.player = player;
And for the question what is this.player = player?
this refers to the current object
For example:
public class myClass{
int x;
public myClass(int x){
this.x = x;
}
}
In the above example, you have used this because, you want to assign value of x to the x(attribute of myClass).
PS: If you are confused with this you can easily do the following:
Change your variable name to something else, may be mPlayer
and change
this.player = player to mPlayer = player;
Edited:
You have declared the YouTubePlayer outside the class. Move it inside i.e. Before overriding onCreate(..) method.
Updated:
Since the player is not attribute of the class, it won't know what it is. This is similar to not declaring any variable.

Categories