Android Studio - Chat not displaying - java

Main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp"
android:id="#+id/activity_main"
tools:context="com.example.syafiq.mychatapp.MainActivity">
<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:src="#drawable/ic_send"
android:id="#+id/fab"
android:tint="#android:color/white"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
app:fabSize="mini"
/>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toLeftOf="#+id/fab"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
>
<EditText
android:id="#+id/messageinput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/fab"
android:layout_centerHorizontal="true"
android:hint="Message..." />
</android.support.design.widget.TextInputLayout>
<ListView
android:id="#+id/list_of_message"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:layout_above="#+id/fab"
android:dividerHeight="16dp"
android:divider="#android:color/transparent"
android:layout_marginBottom="16dp"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
Maincode
private static int SIGN_IN_REQUEST_CODE =1;
//private List<ChatMessage> list = new ArrayList<ChatMessage>();
FirebaseListAdapter<ChatMessage> adapter;
RelativeLayout activity_main;
FloatingActionButton fab;
FirebaseDatabase db = FirebaseDatabase.getInstance();
DatabaseReference myRef = db.getReference("message");
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
if (item.getItemId() == R.id.menu_signout)
{
AuthUI
.getInstance()
.signOut(this)
.addOnCompleteListener(
new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task)
{
Snackbar
.make(
activity_main,
"You have been signed out.",
Snackbar.LENGTH_SHORT
).show()
;
finish();
}
}
)
;
}
return true;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (resultCode==SIGN_IN_REQUEST_CODE)
{
if (resultCode==RESULT_OK)
{
Snackbar
.make(
activity_main,
"Successfully signed in!",
Snackbar.LENGTH_SHORT
).show()
;
displayChatMessage();
}
else
{
Snackbar
.make(
activity_main,
"We couldn't sign you in. Please try again lter!",
Snackbar.LENGTH_SHORT
).show()
;
finish();
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.main_menu,menu);
return true;
}
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
activity_main = (RelativeLayout) findViewById(R.id.activity_main);
fab = (FloatingActionButton) findViewById(R.id.fab);
fab
.setOnClickListener(
new View.OnClickListener()
{
#Override
public void onClick(View v)
{
EditText input = (EditText) findViewById(R.id.messageinput);
FirebaseDatabase
.getInstance()
.getReference()
.push()
.setValue(
new ChatMessage(
input.getText().toString(),
FirebaseAuth.getInstance().getCurrentUser().getEmail()
)
)
;
input.setText("");
displayChatMessage();
}
}
)
;
if (FirebaseAuth.getInstance().getCurrentUser()== null)
{
startActivityForResult(
AuthUI
.getInstance()
.createSignInIntentBuilder()
.build(),
SIGN_IN_REQUEST_CODE
);
}
else
{
Snackbar
.make(
activity_main,
"Welcome " + FirebaseAuth
.getInstance()
.getCurrentUser()
.getEmail(),
Snackbar.LENGTH_SHORT
).show()
;
//displayChatMessage();
}
}
DisplaychatMessage() function to display my chat message
private void displayChatMessage() {
Query query = FirebaseDatabase.getInstance().getReference().child("Chats");
ListView listofmsgs = (ListView) findViewById(R.id.list_of_message);
FirebaseListOptions<ChatMessage> options = new FirebaseListOptions
.Builder<ChatMessage>()
.setQuery(query, ChatMessage.class)
.setLayout(R.layout.list_item)
.build()
;
//adapter.startListening();
Log.d("ErrorCheck", "1");
adapter = new FirebaseListAdapter<ChatMessage>(options) {
#Override protected void populateView(View v, ChatMessage model, int position) {
//ChatMessage cm = (ChatMessage) model;
TextView messageText, messageUser, messageTime;
messageText = (TextView) v.findViewById(R.id.messageinput);
messageUser = (TextView) v.findViewById(R.id.message_user);
messageTime = (TextView) v.findViewById(R.id.message_time);
messageText.setText(model.getMessageText().toString());
messageUser.setText(model.getMessageUser());
messageTime
.setText(
android.text.format.DateFormat.format(
"dd-mm-yyyy (HH:mm:ss)",
model.getMessageTime()
)
)
;
Log.d("ErrorCheck", "2");
}
};
listofmsgs.setAdapter(adapter);
adapter.startListening();
}
Hi guys, i did this but it doesn't seem like anything appear on my APP. But the then, when i press send, in my database, my chat appears there but again it doesn't appear on my Chat app. I did a debug log. Errorcheck 1, and 2 to see where the code ends. When i checked, looks like the debug log only display up till ErrorCheck 1 and does not display display 2. How do i solve this?

You've put ErrorCheck 2 in something called an anonymous class. That's why calling your displayChatMessage() will only log ErrorCheck 1. The code in the anonymous FirebaseListAdapter class you defined will only run when it's populateView() method is called. You don't call that method. You call adapter.startListening(); Something, somewhere, needs to call adapter.populateView() before you'll see ErrorCheck 2 logged.
You likely don't want to call it here. You can call it here just for a test but you should track down what is supposed to be calling it.
According to the docs about FirebaseListAdapter
This class is a generic way of backing an Android ListView with a Firebase location. It handles all of the child events at the given Firebase location. It marshals received data into the given class type. Extend this class and provide an implementation of populateView, which will be given an instance of your list item mLayout and an instance your class that holds your data. Simply populate the view however you like and this class will handle updating the list as the data changes.
So trying changing the data and see if that makes you log ErrorCheck 2

Related

FirestoreRecyclerView is not displaying data from Firestore DB after activity restart

I have this activity from my Online Voting Application that has a RecyclerView based on Firestore UI where it displays all of my data with the field, "registrationStatus" that has a value of "Pending". At the application start, the data is displayed but after going to a different activity by interacting with the items on the RecyclerView, then going back again to the previous activity, the data is not displayed but somehow when I touch the blank RecyclerView, I can still access the data that is previously displayed. I can't seem to know where and what code is causing this to happen. If you can lend me a hand on this problem, that would be lovely.
This is at the start of the application:
This is the activity after interacting with the the items from the RecyclerView:
And now going back to the previous activity:
This is the code that is related to the RecyclerView
public class AdminHomepage extends AppCompatActivity {
Button logOut;
FirebaseAuth mAuth = FirebaseAuth.getInstance();
FirebaseFirestore db = FirebaseFirestore.getInstance();
CollectionReference notebookRef = db.collection("Candidates");
RecyclerView recyclerView;
AdminCandidateAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_admin_homepage);
//Buttons
logOut = findViewById(R.id.adminLogOut);
//Recycler View Things
setUpRecyclerView();
//Log-Out Button Tap
logOut.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mAuth.signOut();
Toast.makeText(getApplicationContext(), "Logged Out Successfully", Toast.LENGTH_SHORT).show();
startActivity(new Intent(getApplicationContext(), MainActivity.class));
finish();
}
});
//Click Listener for the RecyclerView
adapter.setOnItemClickListener(new AdminCandidateAdapter.OnItemClickListener() {
#Override
public void onItemClick(DocumentSnapshot documentSnapshot, int position) {
AdminCandidateItem note = documentSnapshot.toObject(AdminCandidateItem.class);
String name = note.getCandidateFullName();
startActivity(new Intent(getApplicationContext(), EvaluateCandidate.class).putExtra("name", name));
}
});
}
private void setUpRecyclerView() {
Query query = notebookRef.whereEqualTo("registrationStatus", "Pending").orderBy("candidateFullName", Query.Direction.ASCENDING);
FirestoreRecyclerOptions<AdminCandidateItem> options = new FirestoreRecyclerOptions.Builder<AdminCandidateItem>()
.setQuery(query, AdminCandidateItem.class)
.build();
adapter = new AdminCandidateAdapter(options);
recyclerView = findViewById(R.id.candidateList);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
recyclerView.setItemAnimator(null);
}
#Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
adapter.stopListening();
}
So I have resolved my problem. It appears that the RecyclerView cannot display the items because I have assigned the RecyclerView to wrap all of its contents. By assigning a custom height size, the items are now being displayed even after the activity restart.
This is the XML code for that part before the height change:
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/candidateList"
android:layout_width="350dp"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="#color/gray"
android:paddingBottom="30dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView7" />
And this is the code after the height change:
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/candidateList"
android:layout_width="350dp"
android:layout_height="300dp"
android:layout_marginTop="10dp"
android:background="#color/gray"
android:paddingBottom="30dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView7" />
So I have set a custom layout_height of 300dp to make space for the items for my RecyclerView
This is now the activity after the change:

listview/adapterview only shows 1 value in all fields

I'm building my first app but I'm having troubles with 1 piece of the code.
When a value is added (in this case a recipe) it saving the name and the the recipe itself.
The name is listed in a listview which is working.
But when I click the value I want to show/edit/delete, it also shows the name in the recipe field.
Can somebody help me / point me in the right direction?
The code is still messy:
My Recipe Listview
public class Recipes extends AppCompatActivity {
private static final String TAG = "Recipes";
DatabaseRecipes mDatabaseRecipes;
ArrayList<RecipeHelper> recipeList;
ListView mListView;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recipes);
recipeList = new ArrayList<>();
mListView = (ListView) findViewById(R.id.listView);
mDatabaseRecipes = new DatabaseRecipes(this);
Cursor data = mDatabaseRecipes.getData();
populateListView();
Button button_add = (Button) findViewById(R.id.button_add);
button_add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.d(TAG, "onClick: Continue to adding Recipes");
toastMessage("Continue to adding Recipes");
Intent intent = new Intent(Recipes.this, AddRecipe.class);
startActivity(intent);
}
});
}
private void populateListView() {
Log.d(TAG, "populateListView: Displaying data in the ListView.");
//get the data and append to a list
Cursor data = mDatabaseRecipes.getData();
ArrayList<String> listData = new ArrayList<>();
while(data.moveToNext()){
//get the value from the database in column 1
//then add it to the ArrayList
listData.add(data.getString(1));
}
//create the list adapter and set the adapter
ListAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, listData);
mListView.setAdapter(adapter);
//set an onItemClickListener to the ListView
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String name = adapterView.getItemAtPosition(i).toString();
String recipe = adapterView.getItemAtPosition(i).toString();
Log.d(TAG, "onItemClick: You Clicked on " + name);
Cursor data = mDatabaseRecipes.getData(); //get the id associated with that name
int itemID = -1;
while(data.moveToNext()){
itemID = data.getInt(0);
}
if(itemID > -1){
Log.d(TAG, "onItemClick: The ID is: " + itemID);
Intent editScreenIntent = new Intent(Recipes.this, EditRecipe.class);
editScreenIntent.putExtra("id",itemID);
editScreenIntent.putExtra("name",name);
editScreenIntent.putExtra("recipe",recipe);
startActivity(editScreenIntent);
}
else{
toastMessage("No ID associated with that ingredient");
}
}
});
}
/**
* customizable toast
* #param message
*/
private void toastMessage(String message){
Toast.makeText(this,message, Toast.LENGTH_SHORT).show();
}
}
My edit recipe:
public class EditRecipe extends AppCompatActivity {
private static final String TAG = "EditRecipe";
private Button button_edit,button_delete,button_back;
public EditText editRecipe, editRecipeName;
DatabaseRecipes mDatabaseRecipe;
private String selectedName, selectedRecipe;
private int selectedID;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_recipe);
button_edit = (Button) findViewById(R.id.button_edit);
button_delete = (Button) findViewById(R.id.button_delete);
button_back = (Button) findViewById(R.id.button_back);
editRecipeName = (EditText) findViewById(R.id.editRecipeName);
editRecipe = (EditText) findViewById(R.id.editRecipe);
mDatabaseRecipe = new DatabaseRecipes(this);
//get the intent extra from the ListDataActivity
Intent receivedIntent = getIntent();
//now get the itemID we passed as an extra
selectedID = receivedIntent.getIntExtra("id",-1); //NOTE: -1 is just the default value
//now get the name we passed as an extra
selectedName = receivedIntent.getStringExtra("name");
//now get the name we passed as an extra
selectedRecipe = receivedIntent.getStringExtra("recipe");
//set the text to show the current selected name
editRecipeName.setText(selectedName);
//set the text to show the current selected name
editRecipe.setText(selectedRecipe);
button_edit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String item = editRecipeName.getText().toString();
String item2 = editRecipe.getText().toString();
if(!item.equals("") && !item2.equals("")){
mDatabaseRecipe.updateName(item,selectedID,selectedName);
mDatabaseRecipe.updateRecipe(item2,selectedID,selectedRecipe);
Intent int1 = new Intent(EditRecipe.this, Recipes.class);
startActivity(int1);
}else{
toastMessage("You must enter a name");
}
}
});
button_delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mDatabaseRecipe.deleteName(selectedID,selectedName);
editRecipeName.setText("");
toastMessage("removed from database");
Intent int1 = new Intent(EditRecipe.this, Recipes.class);
startActivity(int1);
}
});
button_back.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent int1 = new Intent(EditRecipe.this, Recipes.class);
startActivity(int1);
}
});
}
/**
* customizable toast
* #param message
*/
private void toastMessage(String message){
Toast.makeText(this,message, Toast.LENGTH_SHORT).show();
}
}
My editrecipe.xml
<TextView
android:id="#+id/textView2"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#drawable/background"
android:textAllCaps="false"
android:textSize="36sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0" />
<EditText
android:id="#+id/editIngredient"
android:layout_width="wrap_content"
android:layout_height="43dp"
android:layout_marginBottom="284dp"
android:layout_marginEnd="68dp"
android:layout_marginRight="68dp"
android:layout_marginTop="256dp"
android:background="#color/black_overlay"
android:ems="10"
android:inputType="text|textPersonName"
android:text="#string/ingredient"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.96"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/button-recipes" />
<Button
android:id="#+id/button_edit"
android:layout_width="182dp"
android:layout_height="92dp"
android:layout_marginBottom="192dp"
android:background="#android:drawable/alert_dark_frame"
android:text="#string/edit_the_ingredient"
android:textColor="#ffffff"
android:textSize="18sp"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="#+id/button_delete"
android:layout_width="182dp"
android:layout_height="92dp"
android:layout_marginBottom="192dp"
android:background="#android:drawable/alert_dark_frame"
android:text="#string/delete_the_ingredient"
android:textColor="#ffffff"
android:textSize="18sp"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="#+id/button_back"
android:layout_width="182dp"
android:layout_height="92dp"
android:background="#android:drawable/alert_dark_frame"
android:text="#string/Back"
android:textColor="#ffffff"
android:textSize="18sp"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent" />
</android.support.constraint.ConstraintLayout>
In your onItemCLickListener, you are doing:
String name = adapterView.getItemAtPosition(i).toString();
String recipe = adapterView.getItemAtPosition(i).toString();
Exact same function for the two variables, so likely you are getting twice the same information
I don't know how your Recipe class looks, but maybe you want something more like
String name = recipesList.get(i).getName();
String recipe = recipesList.get(i).getRecipe();
Edit:
After reading more carefully I realize you are not creating your listview using the recipesList but the listData list. You are populating it with the results of your cursor but only the fist column each time, so I assume it's always the name. You are not storing your recipe anywhere, you will have to if you want to be able to retrieve it when clicking on an item.
Assuming your Recipe class contains name and recipe, and your database has one column for name and one for recipe, you can do something like this:
Cursor data = mDatabaseRecipes.getData();
ArrayList<String> listData = new ArrayList<>();
while(data.moveToNext()){
//get the value from the database in column 1
//then add it to the ArrayList
listData.add(data.getString(1));
recipesList.add(new Recipe(data.get(NAME_COLUMN), data.get(RECIPE_COLUMN));
}
Then it should work without making too much changes to your code. But ideally you should use only one list if possible.

NullPointerException when try change text in textView from other class

Can u help me understand why when I want set text in TextView, I got NullPointerException? I know, because my TextView is null but how I can get TextView again?
What is my logic:
Start Application
Click button
Go to nullPoint and get data from firebase, when the proccessing is finished back to MainActivity and update text in TextView.
This is my example code:
MainActivity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnAddNewWord = findViewById(R.id.button);
btnAddNewWord.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
nullPoint np = new nullPoint();
np.takeCount();
}
});
}
public void setTextView(int count){
TextView tv = findViewById(R.id.textView);
tv.setText("count = " + count);
}
}
nullPoint
public class nullPoint {
//the class gets asynchronous data from the Firebase database and does not know when the process will end
public void takeCount(){
//det data
//.
//.
// finish
//send data to MainActivity and update textView text
MainActivity ma = new MainActivity();
ma.setTextView(5);
}
}
XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity"
android:layout_gravity="center">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:layout_gravity="center"/>
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
android:layout_gravity="center"/>
</LinearLayout>
I guess the nullPoint class is not inside the MainActivity. As a result, inside your nullPoint class there is no reference for the TextView in which you are trying to set a data.
In your case I would like to suggest you to implement a listener like the following.
public interface FirebaseResponseListener {
void onFirebaseResponseReceived(int count);
}
Now from your MainActivity, you need to implement the listener as follows.
public class MainActivity extends AppCompatActivity implements FirebaseResponseListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnAddNewWord = findViewById(R.id.button);
btnAddNewWord.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
nullPoint np = new nullPoint();
np.listener = this; // Initialize the listener here
np.takeCount();
}
});
}
public void setTextView(int count){
TextView tv = findViewById(R.id.textView);
tv.setText("count = " + count);
}
#Override
void onFirebaseResponseReceived(int count) {
setTextView(count);
}
}
And you have to add a listener in your nullPoint class as well.
public class nullPoint {
public FirebaseResponseListener listener;
//the class gets asynchronous data from the Firebase database and does not know when the process will end
public void takeCount(){
//det data
//.
//.
// finish
//send data to MainActivity and update textView text
listener.onFirebaseResponseReceived(5);
}
}
Hope that solves your problem.

How can I transfer some value between activities in Android

I tried to send a int value from current activity to the new one, here is the parts in current activity.
dialog.setPositiveButton("4 players", new OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, "Start a new game!", Toast.LENGTH_SHORT).show();
// need send extra value to PlayerBoardActivity to decide how many buttons I should have
Intent intent = new Intent(MainActivity.this,
PlayBoardActivity.class);
intent.putExtra(PLAYER_NO, 4);
startActivity(intent);
}
});
dialog.setNegativeButton("2 players", new OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, "Start a new game!", Toast.LENGTH_SHORT).show();
// need send extra value to PlayerBoardActivity to decide how many buttons I should have
Intent intent = new Intent(MainActivity.this,
PlayBoardActivity.class);
intent.putExtra(PLAYER_NO, 2);
startActivity(intent);
}
});
The problem is, I create 2 layout files for the new activity. When I press the negative button in the dialog for example, what I want is let the new activity (PlayerBoardActivity in my case) load the layout file corresponding to the value I have sent by "intent.putExtra(PLAYER_NO, 2); "
The code in the new activity is
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final String PLAYER_NO = "the number of players";
Bundle b = getIntent().getExtras();
int a = b.getInt(PLAYER_NO);
if (b != null) {
if (a == 2) {
setContentView(R.layout.two_player);
}
if(a == 4){
setContentView(R.layout.four_player);
}
}
}
I do want to know whether I can load different layout file in this way? Or is there any better solution for my problem.
Thank you all in advance.
If you use
intent.putExtra(PLAYER_NO, 2);
you should call following code to get values (without using "Bundle"):
getIntent().getIntExtra(PLAYER_NO, -1)
In your code, the problem is in your second activity to which you are calling.
You are trying to fetching the values from intent in incorrect way.
Try this in your second activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
int b = intent.getIntExtra(PLAYER_NO, 0);
if (b == 2) {
setContentView(R.layout.two_player);
}
if(b == 4){
setContentView(R.layout.four_player);
}
}
Ji Yang... it is fine..if both the layout content the same kind of structure and dealing with different resources of any layout in the same activity is not so difficult..
suppose layout two_player.xml is
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="6dp"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:orientation="vertical">
<TextView
android:id="#+id/textview1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#777370"
android:textSize="16sp"
android:paddingLeft="5dp"
android:text="Dummy Text"
android:visibility="gone"
android:textStyle="bold"/>
</RelativeLayout>
and layout four_player.xml is something like that
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="6dp"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:orientation="vertical">
<ImageView
android:id="#+id/iv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/order_content"
android:src="#drawable/order_next_sap"
android:layout_alignLeft="#+id/order_content"/>
<ImageView
android:id="#+id/iv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/order_content"
android:src="#drawable/order_next_sap"
android:layout_alignLeft="#+id/order_content"/>
</RelativeLayout>
means ...both layout of different defination.. than its difficult to use resource of both layout in same activity and its not good too..
The better solution in this case is to create fragment of both layout
class TwoPlayerFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v=inflater.inflate(R.layout.two_player, container, false);
return v;
}
}
class FourPlayerFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v=inflater.inflate(R.layout.four_player, container, false);
return v;
}
}
and use the fragment according to the intent value pass from dialog..
try this,
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final String PLAYER_NO = "the number of players";
Intent b = getIntent();
int a = b.getExtras().getInt(PLAYER_NO);
if (b != null) {
if (a == 2) {
setContentView(R.layout.two_player);
}
if(a == 4){
setContentView(R.layout.four_player);
}
}
}
You are doing very wrong way. You should use fragment for this. You should create two fragment in which you can inflate different different layout. But this is your call.
From PlayBoardActivity you are sending data like :
intent.putExtra(PLAYER_NO, 4);
So in new activity you need to retreive like:
int b=getIntent.getIntExtra(PLAYER_NO,defaulValue);
you are trying to get value from bundle which is wrong.

Android - implement pull to refresh like Chrome

I was able to find many implementations of pull to refresh for android apps. However, I can't find the one specific that I want. It's already used in Google Chrome for Android, but also other apps use the same way (NovaLauncher, AliExpress and many others).
This is how does it look like:
When you pull down, there is small circle arrow shown. How can I implement the same in my app?
Try this.
Layout XML:
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swipe_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="#string/hello_world"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:gravity="center"/>
</ScrollView>
</android.support.v4.widget.SwipeRefreshLayout>
MainActivity (which implements SwipeRefreshLayout):
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
swipeLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container);
swipeLayout.setOnRefreshListener(this);
swipeLayout.setColorScheme(android.R.color.holo_blue_bright,
android.R.color.holo_green_light,
android.R.color.holo_orange_light,
android.R.color.holo_red_light);
}
#Override public void onRefresh() {
new Handler().postDelayed(new Runnable() {
#Override public void run() {
swipeLayout.setRefreshing(false);
}
}, 5000);
}
For more, check this link:
http://www.androidhive.info/2015/05/android-swipe-down-to-refresh-listview-tutorial/
There is a nice tutorial about it.
Basically you need to put something you want to refresh inside SwipeRefreshLayout
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/activity_main_swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ListView
android:id="#+id/activity_main_listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
</ListView>
</android.support.v4.widget.SwipeRefreshLayout>
Set adapter
class MainActivity extends Activity {
ListView mListView;
SwipeRefreshLayout mSwipeRefreshLayout;
Adapter mAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.acivity_main);
SwipeRefreshLayout mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.activity_main_swipe_refresh_layout);
mListView = findViewById(R.id.activity_main_list_view);
mListView.setAdapter(new ArrayAdapter<String>(){
String[] fakeTweets = getResources().getStringArray(R.array.fake_tweets);
mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, fakeTweets)
listView.setAdapter(mAdapter);
});
}
}
And attach setOnRefreshListener
#Override
public void onCreate(Bundle savedInstanceState) {
...
listView.setAdapter();
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
doSomething();
}
I implemented this in my xhtml page. Works great.
<script type="text/javascript"> //<![CDATA[
window.addEventListener('load', function() {
var maybePreventPullToRefresh = false;
var lastTouchY = 0;
var touchstartHandler = function(e) {
if (e.touches.length != 1) return;
lastTouchY = e.touches[0].clientY;
// Pull-to-refresh will only trigger if the scroll begins when the
// document's Y offset is zero.
maybePreventPullToRefresh =
window.pageYOffset == 0;
}
var touchmoveHandler = function(e) {
var touchY = e.touches[0].clientY;
var touchYDelta = touchY - lastTouchY;
lastTouchY = touchY;
if (maybePreventPullToRefresh) {
// To suppress pull-to-refresh it is sufficient to preventDefault the
// first overscrolling touchmove.
maybePreventPullToRefresh = false;
if (touchYDelta > 0) {
e.preventDefault();
return;
}
}
}
document.addEventListener('touchstart', touchstartHandler, false);
document.addEventListener('touchmove', touchmoveHandler, false); });
//]]> </script>

Categories