I want to know what is the best way to use a Asynctask class(LocationAsyncTask.java) with an Activity to change UI data(ListView).
I have this exception error:
Error:(40, 5) error: method does not override or implement a method from a supertype
EDITED:
I have this Asynctask class(LocationAsyncTask.java):
public abstract class LocationAsyncTask extends AsyncTask{
public ArrayList<Location> locationList;
public Context context;
public LocationAsyncTask(Context context) {
this.context = context;
}
#Override
protected Object doInBackground(Object[] objects) {
try {
//These lines are an example(I will obtain the data via internet)
Location ejemplo = new Location("Locality1","name","address");
Location ejemplo2 = new Location("Locality2","name2","address2");
locationList = new ArrayList<Location>();
locationList.add(ejemplo);
locationList.add(ejemplo2);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {}
}
And this is my Activity class:
public class LocationNativeActivity extends Activity {
ArrayList<Location> locationList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LocationAsyncTask myTask = new LocationAsyncTask(this){
#Override
protected void onPostExecute(Void aVoid) {
ListView s = (ListView)(findViewById(R.id.lvlocationnative));
ArrayAdapter<Location> adapter = new ArrayAdapter<Location>(context, android.R.layout.simple_list_item_1, locationList);
s.setAdapter(adapter);
}
};
myTask.execute();
}
}
And this is my layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="#+id/lvlocationnative"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
This is my Location class:
public class Location {
private String addressLocality;
private String name;
private String address;
public Location(String addressLocality,String name, String address) {
this.addressLocality = addressLocality;
this.name = name;
this.address = address;
}
public String getAddressLocality() {
return addressLocality;
}
public void setAddressLocality(String addressLocality) {
this.addressLocality = addressLocality;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
#Override
public String toString() {
return this.addressLocality;
}
}
With this code I can not insert data in the Listview, any suggestions?
I check these post:
https://stackoverflow.com/a/15409989/3739382
https://stackoverflow.com/a/35193172/3739382
There are plenty of issues with your approach and #Jyoti has just highlighted one of them. You cannot simply use ArrayAdapter as it is with complex object. It won't yield useful results. Instead you need to create CustomAdapter.
Create Custom Item view lets say item_location.xml under layout folder and put following code:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent" >
<TextView
android:id="#+id/tvaddressLocality"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:text="Address Locality" />
<TextView
android:id="#+id/tvName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Name" />
<TextView
android:id="#+id/tvAddress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Address" /></LinearLayout>
Create CustomAdapter class as follows:
import android.content.Context;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import java.util.ArrayList;
public class CustomLocationAdapter extends ArrayAdapter<Location> {
public CustomLocationAdapter(#NonNull Context context, ArrayList<Location> locations) {
super(context,0, locations);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
Location location = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_location, parent, false);
}
// Lookup view for data population
TextView tvAddressLocality = (TextView) convertView.findViewById(R.id.tvaddressLocality);
TextView tvName = (TextView) convertView.findViewById(R.id.tvName);
TextView tvAddress = (TextView) convertView.findViewById(R.id.tvAddress);
// Populate the data into the template view using the data object
tvAddressLocality.setText(location.getAddressLocality());
tvName.setText(location.getName());
tvAddress.setText(location.getAddress());
// Return the completed view to render on screen
return convertView;
}
}
Update your LocationAsyncTask as follows:
public class LocationAsyncTask extends AsyncTask {
private ArrayList<Location> locationList;
private final WeakReference<ListView> listViewWeakReference;
private Context context;
public LocationAsyncTask(ListView listView, Context context) {
this.listViewWeakReference = new WeakReference<>(listView);
this.context = context;
}
#Override
protected Object doInBackground(Object[] objects) {
try {
//These lines are an example(I will obtain the data via internet)
Location ejemplo = new Location("Locality1s", "name", "address");
Location ejemplo2 = new Location("Locality2", "name2", "address2");
locationList = new ArrayList<Location>();
locationList.add(ejemplo);
locationList.add(ejemplo2);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
ArrayAdapter<Location> adapter = new CustomLocationAdapter(context, locationList);
listViewWeakReference.get().setAdapter(adapter);
}
}
Update you LocationNativeActivity.onCreate() as follows:
ListView listView = LocationNativeActivity.this.findViewById(R.id.lvlocationnative);
LocationAsyncTask myTask = new LocationAsyncTask(listView, this);
myTask.execute();
You can replace your code:
LocationAsyncTask myTask = new LocationAsyncTask(this);
as:
LocationAsyncTask myTask = new LocationAsyncTask(this){
#Override
protected void onPostExecute(Void aVoid) {
ListView s = (ListView)(findViewById(R.id.lvlocationnative));
ArrayAdapter<Location> adapter = new ArrayAdapter<Location>(context, android.R.layout.simple_list_item_1, locationList);
s.setAdapter(adapter);
}
};
In your Async task:
Make the arrayList as public
Use this onPostExecute() method:
protected void onPostExecute(Void aVoid) {}
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
i have a view that i want to set it clickable to open a new activity. the code runs without any errors but when i click on a list in the main activity, nothing happens. the list displays alright but when a particular data is clicked, nothing at all happens. this is the code for the adapter
package com.example.helpresponse;
import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Locale;
public class TargetDataAdapter extends RecyclerView.Adapter<TargetDataAdapter.TargetViewHolder>{
ArrayList<AndroidTargets> targetsArrayList;
private Context context;
private HandleClick mHandleClick;
public TargetDataAdapter(ArrayList<AndroidTargets> mTargetData) {
targetsArrayList = mTargetData;
}
public void setmHandleClick(HandleClick handleClick) {
this.mHandleClick = handleClick;
}
#NonNull
#Override
public TargetViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
context = viewGroup.getContext();
View v= LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.target_row,viewGroup,false);
return new TargetViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull TargetViewHolder viewHolder, int i) {
viewHolder.androidTargetName.setText(targetsArrayList.get(i).FIELD1 );
viewHolder.androidTargetNumber.setText(String.format(Locale.getDefault(), "API Level: %d", targetsArrayList.get(i).FIELD2));
viewHolder.androidTargetShortName.setText(targetsArrayList.get(i).FIELD3);
viewHolder.myClickableView.setClickable(true);
/*
viewHolder.myClickableView.setOnClickListener((v) -> {
Intent intent = new Intent(context, MapsActivity.class);
//int myData = 1;
//intent.putExtra("myDataKey", myData);
//more intent.putExtra(s) as needed
context.startActivity(intent);
});
*/
viewHolder.myClickableView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Do your stuff
Intent intent = new Intent(context, MapsActivity.class);
int myData = 1;
intent.putExtra("myDataKey", myData);
//more intent.putExtra(s) as needed
context.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
if(targetsArrayList == null)
return 0;
return targetsArrayList.size();
}
public class TargetViewHolder extends RecyclerView.ViewHolder {
protected TextView androidTargetName;
protected TextView androidTargetNumber;
protected TextView androidTargetShortName;
protected LinearLayout myClickableView;
public TargetViewHolder(#NonNull View itemView) {
super(itemView);
myClickableView = itemView.findViewById(R.id.linearLayout);
androidTargetShortName = itemView.findViewById(R.id.textView2);
androidTargetName = itemView.findViewById(R.id.textView3);
androidTargetNumber = itemView.findViewById(R.id.textView4);
}
}
public interface HandleClick {
void onItemClick(int index);
}
}
this code is the main activity
package com.example.helpresponse;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.List;
public class ShowStudentDetailsActivity extends AppCompatActivity {
DatabaseReference databaseReference;
ProgressDialog progressDialog;
List<StudentDetails> list = new ArrayList<>();
RecyclerView recyclerView;
RecyclerView.Adapter adapter ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_student_details);
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(ShowStudentDetailsActivity.this));
progressDialog = new ProgressDialog(ShowStudentDetailsActivity.this);
progressDialog.setMessage("Loading Data from Firebase Database");
progressDialog.show();
databaseReference = FirebaseDatabase.getInstance().getReference("Police").child("Chats");
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
StudentDetails studentDetails = dataSnapshot.getValue(StudentDetails.class);
list.add(studentDetails);
}
adapter = new RecyclerViewAdapter(ShowStudentDetailsActivity.this, list);
recyclerView.setAdapter(adapter);
progressDialog.dismiss();
}
#Override
public void onCancelled(DatabaseError databaseError) {
progressDialog.dismiss();
}
});
}
}
this code is the layout.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
>
<TextView
android:id="#+id/textView2"
android:textColor="#color/colorPrimary"
style="#style/Base.TextAppearance.AppCompat.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:gravity="center"
android:text="textview"
android:minWidth="100dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:clickable="true"/>
<LinearLayout
android:id="#+id/linearLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/textView2"
app:layout_constraintTop_toTopOf="parent"
android:clickable="true"
>
<TextView
android:id="#+id/textView3"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
android:layout_marginBottom="8dp"
android:text="textview"
android:clickable="true"/>
<TextView
android:layout_marginTop="8dp"
android:id="#+id/textView4"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="textview"
android:clickable="true"/>
</LinearLayout>
</android.support.constraint.ConstraintLayout>
please help, thank you
You are not using your implementation, this should solve your problem.
public class ShowStudentDetailsActivity extends AppCompatActivity {
DatabaseReference databaseReference;
ProgressDialog progressDialog;
List<StudentDetails> list = new ArrayList<>();
RecyclerView recyclerView;
TargetDataAdapter adapter;
...
adapter = new TargetDataAdapter(list);
The problem is with you interface with you even you are not using in MainActivity.
Ex how to implement interface.
Step : 1 create interface in adapter :
public interface IHomeSelector{
void onCategorySelected(int postion);
}
Step : 2 In ViewHolder use interface
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
private TextView category;
private ImageView category_icon;
private IHomeSelector iHomeSelector;
public ViewHolder(#NonNull View itemView, IHomeSelector iHomeSelector) {
super(itemView);
category = itemView.findViewById(R.id.category_title);
category_icon = itemView.findViewById(R.id.category_icon);
this.iHomeSelector = iHomeSelector;
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
iHomeSelector.onCategorySelected(getAdapterPosition());
}
}
Step :3 Pass interface in adapter constructor
public class HomeRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private ArrayList<String> mCategories = new ArrayList<>();
private Context mContext;
private IHomeSelector mIHomeSelector;
public HomeRecyclerAdapter(ArrayList<String> mCategories, Context mContext, IHomeSelector mIHomeSelector) {
this.mCategories = mCategories;
this.mContext = mContext;
this.mIHomeSelector = mIHomeSelector;
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(mContext).inflate(R.layout.layout_category_list_item, null);
return new ViewHolder(view, mIHomeSelector);
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder viewHolder, int i) {
((ViewHolder)viewHolder).category.setText(mCategories.get(i));
RequestOptions requestOptions = new RequestOptions()
.error(R.drawable.ic_launcher_background);
Drawable iconResource = null;
switch(mCategories.get(i)){
case "Music":{
iconResource = ContextCompat.getDrawable(mContext, R.drawable.ic_audiotrack_white_24dp);
break;
}
case "Podcasts":{
iconResource = ContextCompat.getDrawable(mContext, R.drawable.ic_mic_white_24dp);
break;
}
}
Glide.with(mContext)
.setDefaultRequestOptions(requestOptions)
.load(iconResource)
.into(((ViewHolder)viewHolder).category_icon);
}
#Override
public int getItemCount() {
return mCategories.size();
}
Last step implement interface in activity :
public class HomeFragment extends Fragment implements HomeRecyclerAdapter.IHomeSelector
{
private static final String TAG = "HomeFragment";
// UI Components
private RecyclerView mRecyclerView;
// Vars
private HomeRecyclerAdapter mAdapter;
private ArrayList<String> mCategories = new ArrayList<>();
private IMainActivity mIMainActivity;
public static HomeFragment newInstance(){
return new HomeFragment();
}
#Override
public void onHiddenChanged(boolean hidden) {
if(!hidden){
mIMainActivity.setActionBarTitle(getString(R.string.categories));
}
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_home, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
initRecyclerView(view);
mIMainActivity.setActionBarTitle(getString(R.string.categories));
}
private void initRecyclerView(View view){
mRecyclerView = view.findViewById(R.id.recycler_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mAdapter = new HomeRecyclerAdapter(mCategories, getActivity(), this); // passing 3 rd parameter this for interface
mRecyclerView.setAdapter(mAdapter);
}
#Override
public void onCategorySelected(int postion) {
Log.d(TAG, "onCategorySelected: list item is clicked!");
//Here implement you code not in adapter
}
}
Just follow this step if still stuck let me know.Happy Coding!!!
First you created a custom adapter and did not use it.
secondly you're trying to reduce the work load of the adapter by abstracting some of it functionality like onClickListeners, yet you still perform the onClick inside the adapter which almost defeat the purpose of the abstraction.
Finally, interfaces are basically to be implemented and I'm curious on how you missed that.
Below is a commented and correct snippet of your code, you will understand it better if and only if you read the comments.
First your adapter:
public class TargetDataAdapter extends RecyclerView.Adapter<TargetDataAdapter.TargetViewHolder>{
ArrayList<AndroidTargets> targetsArrayList;
private Context context;
private HandleClick mHandleClick;
public TargetDataAdapter(ArrayList<AndroidTargets> mTargetData) {
targetsArrayList = mTargetData;
}
public void setmHandleClick(HandleClick handleClick) {
this.mHandleClick = handleClick;
}
#NonNull
#Override
public TargetViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
context = viewGroup.getContext();
View v= LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.target_row,viewGroup,false);
return new TargetViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull TargetViewHolder viewHolder, int i) {
viewHolder.androidTargetName.setText(targetsArrayList.get(i).FIELD1 );
viewHolder.androidTargetNumber.setText(String.format(Locale.getDefault(), "API Level: %d", targetsArrayList.get(i).FIELD2));
viewHolder.androidTargetShortName.setText(targetsArrayList.get(i).FIELD3);
viewHolder.myClickableView.setClickable(true);
viewHolder.myClickableView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Do your stuff
mHandleClick.onItemClick(i);//here is where you call the onItemClick method in the interface
}
});
}
public interface HandleClick {
void onItemClick(int index);
}
}
Your ShowStudentDetailsActivity:
//Take note of the implements keyword
public class ShowStudentDetailsActivity extends AppCompatActivity, implements HandleClick {
DatabaseReference databaseReference;
ProgressDialog progressDialog;
ArrayList<StudentDetails> list = new ArrayList<>();
RecyclerView recyclerView;
TargetDataAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_student_details);
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(ShowStudentDetailsActivity.this));
progressDialog = new ProgressDialog(ShowStudentDetailsActivity.this);
progressDialog.setMessage("Loading Data from Firebase Database");
progressDialog.show();
databaseReference = FirebaseDatabase.getInstance().getReference("Police").child("Chats");
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
StudentDetails studentDetails = dataSnapshot.getValue(StudentDetails.class);
list.add(studentDetails);
}
adapter = new TargetDataAdapter(list);
/*The this keyword below parses whatever setmHandleClick() method needs that's present in that same class, which is the onItemClick() method in the interface that we implemented. So, the this keyword simply is a reference to ShowStudentDetailsActivity as an object, including all it resources like context */
adapter.setmHandleClick(this)
recyclerView.setAdapter(adapter);
progressDialog.dismiss();
}
#Override
public void onCancelled(DatabaseError databaseError) {
progressDialog.dismiss();
}
});
}
/* This is the result of the implemented interface above using implements keyword
you will note that without the below method, our class will show error and it's
basically telling us to do like below. So, when you implement an interface, you will be forced to have all its method implemented like below also.
I will suggest you read more on interface in java.*/
#Override
void onItemClick(int index){
//note that we have moved the code that was in the adapter back to the activity it self.
Intent intent = new Intent(this, MapsActivity.class);
int myData = index;
intent.putExtra("myDataKey", myData);
startActivity(intent);
}
}
That's it.
Bonus, below is a little bit more better approach and readable version.
Firstly I will put my interface in a separate file.
public interface HandleClick {
void onItemClick(int index);
}
Secondly my adapter:
public class TargetDataAdapter extends RecyclerView.Adapter<TargetDataAdapter.TargetViewHolder>{
private ArrayList<AndroidTargets> targetsArrayList;
private HandleClick mHandleClick;
/*Note that the constructor now take two params which helps us get ride of setmHandleClick() method.*/
public TargetDataAdapter(ArrayList<AndroidTargets> mTargetData, HandleClick handleClick) {
targetsArrayList = mTargetData;
mHandleClick = handleClick;
}
#NonNull
#Override
public TargetViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View v= LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.target_row,viewGroup,false);
return new TargetViewHolder(v);
}
/* There is an interesting way to make below code neater by abstracting it back to the Activity incharge, let me know if you want that...priority now is to focus on fixing your issue. */
#Override
public void onBindViewHolder(#NonNull TargetViewHolder viewHolder, int i) {
viewHolder.androidTargetName.setText(targetsArrayList.get(i).FIELD1 );
viewHolder.androidTargetNumber.setText(String.format(Locale.getDefault(), "API Level: %d", targetsArrayList.get(i).FIELD2));
viewHolder.androidTargetShortName.setText(targetsArrayList.get(i).FIELD3);
viewHolder.myClickableView.setClickable(true);
viewHolder.myClickableView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mHandleClick.onItemClick(i);
}
});
}
}
My ShowStudentDetailsActivity:
//Note that you can implement more than one interfaces, that's one of it's beauty.
public class ShowStudentDetailsActivity extends AppCompatActivity, implements HandleClick {
private DatabaseReference databaseReference;
ProgressDialog progressDialog;
private ArrayList<StudentDetails> list = new ArrayList<>();
private RecyclerView recyclerView;
private TargetDataAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_student_details);
initRecyclerView();
initProgressDialog("Loading Data from Firebase Database");
progressDialog.show();
databaseReference = FirebaseDatabase.getInstance().getReference("Police").child("Chats");
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
StudentDetails studentDetails = dataSnapshot.getValue(StudentDetails.class);
list.add(studentDetails);
}
adapter = new TargetDataAdapter(list, this);
recyclerView.setAdapter(adapter);
progressDialog.dismiss();
}
#Override
public void onCancelled(DatabaseError databaseError) {
progressDialog.dismiss();
}
});
}
private void initProgressDialog(String msg){
progressDialog = new ProgressDialog(this);
progressDialog.setMessage(msg);
}
private void initRecyclerView(){
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
/*LinearLayoutManager.VERTICAL is to set the orientation of my list items in the recyclerView, and the boolean value When set to true, layouts from end to start, otherwise start to end.*/
recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
}
#Override
void onItemClick(int index){
Intent intent = new Intent(this, MapsActivity.class);
int myData = index;
intent.putExtra("myDataKey", myData);
startActivity(intent);
}
}
I'm trying fetch all documents using FirestoreRecyclerAdapter here if there are 7 documents the RecyclerView items successfully populates with 7 items but here problem is the items which are having a text view are not getting populated with document names. Please take a look at my source code:
FriendsResponse Class:
#IgnoreExtraProperties
public class FriendsResponse {
FirebaseFirestore db;
public String getTable1() {
return Table1;
}
public void setTable1(String table1) {
Table1 = table1;
}
private String Table1;
public FriendsResponse() {
}
public FriendsResponse(String Table1) {
this.Table1 = Table1;
}
}
TableList Fragment where recyclerview is initialized:
public class TableListFragment extends Fragment{
private FirebaseFirestore db;
private FirestoreRecyclerAdapter adapter;
String documentnm;
RecyclerView recyclerView;
FloatingActionButton addt;
private StaggeredGridLayoutManager _sGridLayoutManager;
public static TableListFragment newInstance() {
TableListFragment fragment = new TableListFragment();
return fragment;
}
public TableListFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_tablelist, container, false);
recyclerView = view.findViewById(R.id.rectab);
addt=view.findViewById(R.id.addtab);
init();
getFriendList();
addt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
return view;
}
private void init(){
_sGridLayoutManager = new StaggeredGridLayoutManager(3,
StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(_sGridLayoutManager);
db = FirebaseFirestore.getInstance();
}
private void getFriendList(){
Query query = db.collection("Order");
FirestoreRecyclerOptions<FriendsResponse> response = new FirestoreRecyclerOptions.Builder<FriendsResponse>()
.setQuery(query, FriendsResponse.class)
.build();
adapter = new FirestoreRecyclerAdapter<FriendsResponse, FriendsHolder>(response) {
#Override
public void onBindViewHolder(FriendsHolder holder, int position, FriendsResponse model) {
holder.exname.setText(model.getTable1());
holder.itemView.setOnClickListener(v -> {
Snackbar.make(recyclerView, model.getTable1(), Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
});
}
#Override
public FriendsHolder onCreateViewHolder(ViewGroup group, int i) {
View view = LayoutInflater.from(group.getContext())
.inflate(R.layout.list_item, group, false);
return new FriendsHolder(view);
}
#Override
public void onError(FirebaseFirestoreException e) {
Log.e("error", e.getMessage());
}
};
adapter.notifyDataSetChanged();
recyclerView.setAdapter(adapter);
}
public class FriendsHolder extends RecyclerView.ViewHolder {
TextView exname;
public FriendsHolder(View itemView) {
super(itemView);
exname= itemView.findViewById(R.id.topicname);
}
}
#Override
public void onStart() {
super.onStart();
adapter.startListening();
}
#Override
public void onStop() {
super.onStop();
adapter.stopListening();
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
}
#Override
public void onDetach() {
super.onDetach();
}
}
This is the code of list_item:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView android:id="#+id/cardvw"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardCornerRadius="6dp"
card_view:cardElevation="3dp"
card_view:cardUseCompatPadding="true"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:card_view="http://schemas.android.com/apk/res-auto">
<LinearLayout android:orientation="vertical" android:padding="5dp" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_margin="5dp">
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/topiclogo"
android:layout_width="match_parent"
android:layout_gravity="center"
android:src="#drawable/table"
android:layout_height="wrap_content"
/>
<TextView android:textSize="15sp"
android:textStyle="bold"
android:textAlignment="center"
android:textColor="#ffffa200"
android:id="#+id/topicname"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</android.support.v7.widget.CardView>
As I understand, you want to set the id of the document to that TextView. So because those names are actually documents ids, you should use the following lines of code inside onBindViewHolder() method:
String id = getSnapshots().getSnapshot(position).getId();
holder.exname.setText(id);
The POJO class that you are using is useful when getting the properties of the documents, not to get the document ids.
Can anyone here help me?
how to display the "Episode" and "Pemeran" sections in the recyclerView on the second display in the following image.
I use the same method as "liveTV" but it doesn't work / appears anything, because of the many children in the Episode and Pemeran tables?
please help, thank you
Firebase Realtime-database picture]
Application Concept
dbDrakorAdapter.java - Models
public class dbDrakorAdapter {
private String LinkMovie;
private String List;
private String FotoPemain;
private String NamaPemain;
public dbDrakorAdapter (String linkMovie, String list, String fotoPemain, String namaPemain) {
LinkMovie = linkMovie;
List = list;
FotoPemain = fotoPemain;
NamaPemain = namaPemain;
}
public class Episode {
List<EpisodeDetails> episodeDetails;
}
public class EpisodeDetails {
// public Long chapterId;
public String LinkMovie;
public String List;
}
public class Pemeran {
List<PemeranDetails> pemeranDetails;
}
public class PemeranDetails {
// public Long chapterId;
public String LinkMovie;
public String List;
}
#PropertyName("LinkMovie")
public String getLinkMovie() { return LinkMovie; }
#PropertyName("List")
public String getList() { return List; }
#PropertyName("FotoPemain")
public String getFotoPemain() { return FotoPemain; }
#PropertyName("NamaPemain")
public String getNamaPemain() { return NamaPemain; }
#Exclude
public Map<String, Object> toMap() {
HashMap<String, Object> result = new HashMap<>();
result.put("List", List);
result.put("LinkMovie", LinkMovie);
result.put("FotoPemain", FotoPemain);
result.put("NamaPemain", NamaPemain);
return result;
}
}
DrakorActivity.Java
public class DrakorActivity extends AppCompatActivity {
private RecyclerView mEpisodeRV,mPemeranRV;
private FirebaseRecyclerAdapter<dbDrakorAdapter, DrakorActivity.ListEpisode> mListEpisodeAdapter;
private FirebaseRecyclerAdapter<dbDrakorAdapter, DrakorActivity.ListPemeran> mListPemeranAdapter;
FirebaseDatabase firebaseDatabase;
DatabaseReference databaseReference;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drakor);
DatabaseReference database = FirebaseDatabase.getInstance().getReference("SerialDrakor").child("Episode");
Query personsQuery = database.orderByKey();
mEpisodeRV = (RecyclerView) findViewById(R.id.cRecylerDrakorEpisode);
mEpisodeRV.setHasFixedSize(true);
mEpisodeRV.setLayoutManager(new LinearLayoutManager(this));
FirebaseRecyclerOptions personsOptions = new FirebaseRecyclerOptions.Builder<dbDrakorAdapter>().setQuery(personsQuery, dbDrakorAdapter.class).build();
mListEpisodeAdapter = new FirebaseRecyclerAdapter<dbDrakorAdapter, ListEpisode>(personsOptions) {
#Override
protected void onBindViewHolder(DrakorActivity.ListEpisode holder, int position, final dbDrakorAdapter model ) {
holder.setList(model.getList());
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(DrakorActivity.this,"Ini Hanya Iklan , Tidak Dapat Digunakan",Toast.LENGTH_LONG).show();
}
});
}
#Override
public DrakorActivity.ListEpisode onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_drakor_episode, parent, false);
return new DrakorActivity.ListEpisode(view);
}
};
LinearLayoutManager layoutManager = new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false);
mEpisodeRV.setLayoutManager(layoutManager);
mEpisodeRV.setAdapter(mListEpisodeAdapter);
}
#Override
public void onStart() {
super.onStart();
mListEpisodeAdapter.startListening();
// mListPemeranAdapter.startListening();
}
#Override
public void onStop() {
super.onStop();
mListEpisodeAdapter.stopListening();
// mListPemeranAdapter.stopListening();
}
//Episode
public static class ListEpisode extends RecyclerView.ViewHolder{
View mView;
public ListEpisode(View itemView){
super(itemView);
mView = itemView;
}
public void setList (String list){
TextView post_title = (TextView)mView.findViewById(R.id.TxtlistEpisode);
post_title.setText(list);
}
}
activity_drakor.xml
<LinearLayout
android:id="#+id/drakorLyEpisode"
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_below="#id/drakorThumbnail"
android:background="#color/colorAccent"
android:orientation="horizontal">
<android.support.v7.widget.RecyclerView
android:id="#+id/cRecylerDrakorEpisode"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
item_drakor_episode.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="60dp"
android:layout_height="30dp"
android:orientation="horizontal"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:cardBackgroundColor="#090000"
app:cardCornerRadius="15dp">
<TextView
android:id="#+id/TxtlistEpisode"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="#ffffff"
android:textSize="20dp"
android:text="1"
android:textAlignment="center"
android:textStyle="bold" />
</android.support.v7.widget.CardView>
On deep seeing your firebase structure it is difficult to query as you said.So you can change your firebase structure as below
Episode
|
|__Unique_Key
|
|__LinkMovie:"asasa.com
|__List:"1"
|__Epi:"1"
Pemeran
|
|__UniqueKey
|__fotoPermain:"...."
|__NamaPemain:"Ronny"
|__permeranId:"1"
Here,SubNode 1 in your Episode and pemeran Node in your firebase structure is replace as the Child Node of Unique Key.
You can generate Unique Key by push()
Your FirebaseRecyclerAdapters are using the same POJO but they are going to display different information.
For example:
FirebaseRecyclerAdapter<EpisodePojo, DrakorActivity.ListEpisode> listEpisodesAdapter
FirebaseRecyclerAdapter<PemeranPojo, DrakorActivity.ListPemeran> listPemeranAdapter
Your code is not showing any information probably because your DatabaseReference is trying to access "Episode as a child of SerialDrakor" but "SerialDrakor" is a list of objects, therefore, your code will not be able to parse a list of "SerialDrakor" child into "Episode".
You have to retrieve "SerialDrakor" as a list and use the child you need from this list to retrieve the "Episode" and "Pemeran" inside of it.
Here you can see some examples, maybe would be a good idea to use a custom parser.
https://github.com/firebase/FirebaseUI-Android/tree/master/database#using-the-firebaserecycleradapter
Update: What I would do is create a class parsing a "SerialDrakor" item.
class SerialDrakor {
List<Episode> episodeList;
List<Pemeran> pemeranList;
.....
}
Then use a query to retrieve "SerialDrakor"
DatabaseReference database = FirebaseDatabase.getInstance().getReference();
Query serialDrakorQuery = database.child("SerialDrakor").orderByKey();
FirebaseRecyclerOptions personsOptions = new FirebaseRecyclerOptions.Builder<SerialDrakor>().setQuery(serialDrakorQuery, new SnapshotParser<SerialDrakor>() {
#Override
public SerialDrakor parseSnapshot(#NonNull DataSnapshot snapshot) {
// Here fetch the data you want and pass it to your adapters
}
I hope it helps.
I'm trying to add ProgressBar to the bottom of the list while loading next page. How can do it? Is there a way to place my progressbar more efficiently? I saw many uses viewtype in adapter, but i don't really get how it changes. Also, after progressbar ended and new page added, i want the bottom item to scroll for 1 position below.
This is my list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="10dp"
android:orientation="vertical"
android:divider="#android:color/black">
<TextView
android:id="#+id/id"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="5dp"/>
<TextView
android:id="#+id/email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"/>
<TextView
android:id="#+id/phone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginBottom="10dp"/>
</LinearLayout>
<ProgressBar
android:visibility="gone"
android:id="#+id/progressbar"
android:progress="1"
android:layout_width="100dp"
android:layout_height="100dp"
android:indeterminate="true"
android:layout_gravity="center_horizontal"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#ccc"/>
</android.support.v7.widget.CardView>
This is my MyAdapter.java
import android.app.Activity;
import android.content.Context;
import android.service.autofill.Dataset;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import java.util.ArrayList;
import java.util.HashMap;
public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
Context c;
ArrayList<String> id;
ArrayList<String> name;
ArrayList<String> email;
ArrayList<String> phone;
private Activity mactivity;
private final int VIEW_TYPE_ITEM = 0;
private final int VIEW_TYPE_LOADING = 1;
private boolean isLoading;
private int visibleThreshold = 5;
private int lastVisibleItem, totalItemCount;
private OnLoadMoreListener onLoadMoreListener;
public interface OnLoadMoreListener {
void onLoadMore();
}
public MyAdapter(Context c, ArrayList<String> id, ArrayList<String> name, ArrayList<String> email, ArrayList<String> phone) {
this.c = c;
this.id = id;
this.name = name;
this.email= email;
this.phone = phone;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Log.d("viewType", "onCreateViewHolder: "+viewType);
View v = LayoutInflater.from(c).inflate(R.layout.list_item, parent, false);
return new MyViewHolder(v);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.id.setText(id.get(position));
holder.name.setText(name.get(position));
holder.email.setText(email.get(position));
holder.phone.setText(phone.get(position));
}
#Override
public int getItemCount() {
return id.size();
}
}
This is my MainActivity.java
public class MainActivity extends AppCompatActivity {
private String URL = "myURL.php";
private String token = "mytoken";
RecyclerView mrecyclerView;
MyAdapter myAdapter;
ArrayList<String> id = new ArrayList<>();
ArrayList<String> name = new ArrayList<>();
ArrayList<String> email = new ArrayList<>();
ArrayList<String> phone = new ArrayList<>();
String next_page="";
ProgressBar mProgressBar;
private Parcelable recyclerViewState;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mProgressBar =(ProgressBar)findViewById(R.id.progressbar);
mrecyclerView = (RecyclerView) findViewById(R.id.mRecyclerview);
mrecyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this, LinearLayoutManager.VERTICAL, false));
new getJSON().execute();
myAdapter = new MyAdapter(getApplicationContext(), id, name, email, phone);
mrecyclerView.addOnScrollListener(new EndlessRecyclerOnScrollListener() {
#Override
public void onLoadMore() {
if (URL != null) {
//mProgressBar.setVisibility(View.VISIBLE);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
recyclerViewState = mrecyclerView.getLayoutManager().onSaveInstanceState();
URL = next_page;
new getJSON().execute();
}
}, 200);
//mProgressBar.setVisibility(View.GONE);
}
}
});
}
private class getJSON extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(Void v) {
super.onPostExecute(v);
mrecyclerView.getLayoutManager().onRestoreInstanceState(recyclerViewState);
mrecyclerView.setAdapter(myAdapter);
}
#Override
protected Void doInBackground(Void... voids) {
HTTPHandler httpHandler = new HTTPHandler();
String json = httpHandler.makeCall(URL, token);
if (json != null) {
try {
JSONObject jsonObject = new JSONObject(json);
JSONArray jsonArray = jsonObject.getJSONArray("data");
next_page = String.valueOf(jsonObject.get("next_page_url"));
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject obj = jsonArray.getJSONObject(i);
id.add(obj.getString("id"));
name.add(obj.getString("name"));
email.add(obj.getString("email"));
phone.add(obj.getString("phone"));
}
} catch (final JSONException e) {
Log.e("ERROR", "Json parsing error: " + e.getMessage());
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Json parsing error: " + e.getMessage(),
Toast.LENGTH_LONG)
.show();
}
});
}
} else {
Log.e("ERROR", "Couldn't get json from server.");
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Couldn't get json from server. Check LogCat for possible errors!",
Toast.LENGTH_LONG)
.show();
}
});
}
return null;
}
}
}
and i used EndlessRecyclerOnScrollListener.java from here
public abstract class EndlessRecyclerOnScrollListener extends RecyclerView.OnScrollListener {
// public static String TAG = EndlessRecyclerOnScrollListener.class.getSimpleName();
/**
* The total number of items in the dataset after the last load
*/
private int mPreviousTotal=0;
/**
* True if we are still waiting for the last set of data to load.
*/
private boolean mLoading = true;
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int visibleItemCount = recyclerView.getChildCount();
int totalItemCount = recyclerView.getLayoutManager().getItemCount();
int firstVisibleItem = ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPosition();
if (mLoading) {
if (totalItemCount > mPreviousTotal) {
mLoading = false;
mPreviousTotal = totalItemCount;
}
}
int visibleThreshold = 5;
if (!mLoading && (totalItemCount - visibleItemCount)
<= (firstVisibleItem + visibleThreshold)) {
// End has been reached
onLoadMore();
mLoading = true;
}
}
public abstract void onLoadMore();
}
This progressbar should be added in your activity's xml and not in list_item.xml but it is not.
So with this line in your activity class:
mProgressBar =(ProgressBar)findViewById(R.id.progressbar);
the variable mProgressBar is null because it cannot be found inside the activity's xml.
So move the below code from list_item.xml to activity_main.xml:
<ProgressBar
android:visibility="gone"
android:id="#+id/progressbar"
android:progress="1"
android:layout_width="100dp"
android:layout_height="100dp"
android:indeterminate="true"
android:layout_gravity="center_horizontal"/>
I am learning Android myself. Now, I am trying to learn fragments. Here i would like to host fragment on contact activity.
I have 2 issues
Issue 1:
The detail fragment is not showing all data.
for example from my java class .There is
new Contact("Ron", "Thal", "+405-315-2827", "ron#ronthal.com")
On list there is Thal which is lastname. Clicking on it Should show Firstname, lastname, phone and email. But it is displaying only first name but with issue 2
Issue 2:
I have successfully sorted Lastnames alphabetically on the list fragment. How ever, It is not displaying right data on the detail fragment when i use sorted list on list fragment. The detail fragment is showing fragment data in order i have in my pure java class. It should display related data to list.
When i don't sort, the right data is displayed but with only firstname on detail fragment when clicking lastname on list fragment.
How to fix it? Where i have mistaken?
contact activity
public class ContactActivity extends Activity implements ContactListFragment.ContactListListener{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contact);
}
#Override
public void itemClicked(long id){
//method also defined in the listener
View fragmentContainer = findViewById(R.id.fragment_detail_container);
if (fragmentContainer != null){
ContactDetailsFragment detailsFragment = new ContactDetailsFragment();
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
detailsFragment.setContact(id);
fragmentTransaction.replace(R.id.fragment_detail_container, detailsFragment);
//fragmentTransaction.addToBackStack(null);
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
fragmentTransaction.commit();
}
}
}
Contact detail fragment
public class ContactDetailsFragment extends Fragment {
private long contactId;
public ContactDetailsFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
if (savedInstanceState != null){
contactId = savedInstanceState.getLong("contactId");
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_contact_details, container, false);
}
#Override
public void onStart(){
super.onStart();
View view = getView();
if (view != null){
TextView FNameText = (TextView) view.findViewById(R.id.textFName);
Contact contact = myContact[(int) contactId];
FNameText.setText(contact.getFName());
TextView LNameText = (TextView) view.findViewById(R.id.textLName);
LNameText.setText(contact.getLName());
TextView PhoneText = (TextView) view.findViewById(R.id.textPhone);
PhoneText.setText(contact.getPhone());
TextView EmailText = (TextView) view.findViewById(R.id.textEmail);
EmailText.setText(contact.getEmail());
}
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState){
savedInstanceState.putLong("contactId", contactId);
}
public void setContact(long id){
this.contactId = id;
}
}
contact list fragment
public class ContactListFragment extends ListFragment {
//ArrayAdapter<Contact> cAdapter;
ArrayAdapter<String> cAdapter;
interface ContactListListener{
void itemClicked(long id);
}
//add listener to fragment
private ContactListListener listener;
public ContactListFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//String[] lastname = new String[Contact.class]
//cAdapter = new ArrayAdapter<>(inflater.getContext(), R.layout.fragment_contact_list, myContact);
String[] lnames = new String[Contact.myContact.length];
//String[] fnames = new String[Contact.myContact.length];
for (int i = 0; i < lnames.length; i++){
lnames[i] = Contact.myContact[i].getLName();
//fnames[i] = myContact[i].getFName();
}
//ArrayAdapter<String> cAdapter;
//ArrayAdapter<String> cAdapter;
//cAdapter = new ArrayAdapter<>(inflater.getContext(), android.R.layout.simple_list_item_1, myContact);
cAdapter = new ArrayAdapter<>(inflater.getContext(), android.R.layout.simple_list_item_1, lnames);
//to sort alphabetically
/*
cAdapter.sort(new Comparator<Contact>() {
#Override
public int compare(Contact o1, Contact o2) {
return o1.toString().compareToIgnoreCase(o2.toString());
}
});
*/
cAdapter.sort(new Comparator<String>() {
#Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
setListAdapter(cAdapter);
cAdapter.notifyDataSetChanged();
return super.onCreateView(inflater, container, savedInstanceState);
}
#Override
public void onAttach(Activity activity){
super.onAttach(activity);
this.listener = (ContactListListener) activity;
}
#Override
public void onListItemClick(ListView l, View v, int position, long id){
if (listener != null){
listener.itemClicked(id);
}
}
}
fragment contact detail 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">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text=""
android:id="#+id/textFName"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text=""
android:id="#+id/textLName"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text=""
android:id="#+id/textPhone"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text=""
android:id="#+id/textEmail"
/>
</LinearLayout>
contact activity xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_contact"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:baselineAligned="false"
tools:context="edu.uco.rawal.p5rabina.ContactActivity">
<fragment
class="edu.uco.rawal.p5rabina.ContactListFragment"
android:layout_width="0dp"
android:layout_weight ="1"
android:layout_height="match_parent"
android:id="#+id/contact_list_frag"/>
<FrameLayout
android:id="#+id/fragment_detail_container"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="match_parent"
>
</FrameLayout>
</LinearLayout>
Contact.java (Pure java class)
public class Contact {
private String fname, lname, phone, email;
public static final Contact[] myContact = {
new Contact("Rabin", "Awal", "+405-315-0007", "rawal#yahoo.com"),
new Contact("David", "Gilmour", "+405-315-2027", "david#gilmour.com"),
new Contact("James", "Hetfield", "+405-315-2527", "james#metallica.com"),
new Contact("Kirk", "Hammet", "+405-315-2995", "kirk#metallica.com"),
new Contact("Tom", "Morello", "+405-315-2886", "tom#tommorello.com"),
new Contact("Angus", "Young", "+405-315-2831", "angus#acdc.com.au"),
new Contact("Ron", "Thal", "+405-315-2827", "ron#ronthal.com")
};
private Contact(String fname, String lname, String phone, String email){
this.fname = fname;
this.lname = lname;
this.email = email;
this.phone = phone;
}
public String getFName() {
return fname;
}
public String getLName() {
return lname;
}
public String getEmail() {
return email;
}
public String getPhone() {
return phone;
}
/*
public void setFName(String fname) {
this.fname = fname;
}
public void setLName(String lname) {
this.lname = lname;
}
public void setPhone(String phone) {
this.phone = phone;
}
public void setEmail(String email) {
this.email = email;
}
*/
#Override
public String toString() {
//return super.toString();
return fname.toString();
//return this.fname;
}
}
Thank You
it is displaying only first name
In a ListView, that makes sense because an ArrayAdapter<String> will toString your objects, which is return fname.toString(); (which could really just be return fname)
If you mean inside the detail fragment, then in your XML, each TextView should ideally have android:layout_height="wrap_content" instead of match_parent. Otherwise one TextView occupies the whole screen.
I have successfully sorted Lastnames alphabetically on the list fragment.
Okay, then I'm not sure what the problem is... Maybe you meant this was the problem?
cAdapter.sort(new Comparator<Contact>() {
#Override
public int compare(Contact o1, Contact o2) {
return o1.toString().compareToIgnoreCase(o2.toString());
}
});
You have two Contact objects here... If you want to sort by last names, then do that.
cAdapter.sort(new Comparator<Contact>() {
#Override
public int compare(Contact c1, Contact c2) {
return c1.getLName().compareToIgnoreCase(c2.getLName());
}
});
Regarding this code.
String[] lnames = new String[Contact.myContact.length];
//String[] fnames = new String[Contact.myContact.length];
for (int i = 0; i < lnames.length; i++){
lnames[i] = Contact.myContact[i].getLName();
//fnames[i] = myContact[i].getFName();
}
I would recommend you try to lookup how to create a ArrayAdapter<Contact> if you want to display all the information of a Contact rather than just the last/first name.
And I'm also not too sure about using getView() within onStart()... I think you should either use the View from onCreateView or onViewCreated.