I am working on the development of an Android App. In an Activity there will be two tab. Each of the tabs are individual fragments. I am retrieving some JSON data from the server in Async task and setting those data into the TextView of the Fragment Layout.
So far I understand I have to replace the fragment in the main activity to achieve this. I am getting following error while running the app.
java.lang.IllegalStateException: Can't change container ID of fragment MutualFunds{ed3a1c0 #0 id=0x7f080096}: was 2131230870 now 2131230812
at android.support.v4.app.BackStackRecord.doAddOp(BackStackRecord.java:422)
at android.support.v4.app.BackStackRecord.replace(BackStackRecord.java:444)
at android.support.v4.app.BackStackRecord.replace(BackStackRecord.java:434)
at com.testappl.ivest.ICLProducts.changefrag(ICLProducts.java:234)
at com.testappl.ivest.ICLProducts$JsonTask.onPostExecute(ICLProducts.java:207)
at com.testappl.ivest.ICLProducts$JsonTask.onPostExecute(ICLProducts.java:101)
at android.os.AsyncTask.finish(AsyncTask.java:660)
at android.os.AsyncTask.-wrap1(AsyncTask.java)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:677)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:165)
at android.app.ActivityThread.main(ActivityThread.java:6375)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:883)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
Here is my Fragment Activity class:
package com.testappl.ivest;
import android.app.FragmentManager;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.testappl.ivest.model.FundMaster;
/**
* A simple {#link Fragment} subclass.
* Activities that contain this fragment must implement the
* {#link MutualFunds.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {#link MutualFunds#newInstance} factory method to
* create an instance of this fragment.
*/
public class MutualFunds extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private static final String ARG_PARAM3 = "param3";
private static final String ARG_PARAM4 = "param4";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private String mParam3;
private String mParam4;
private static View view;
private OnFragmentInteractionListener mListener;
TextView mBFLabel;
TextView mBFDefintion;
TextView mBFCurrentNAV;
TextView mBFCurrentReturn;
TextView mGFLabel;
TextView mGFDefinition;
TextView mGFCurrentNAV;
TextView mGFCurrentReturn;
public MutualFunds() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment MutualFunds.
*/
// TODO: Rename and change types and number of parameters
public static MutualFunds newInstance(String param1, String param2,String param3,String param4) {
MutualFunds fragment = new MutualFunds();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
args.putString(ARG_PARAM3, param3);
args.putString(ARG_PARAM4, param4);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
mParam3=getArguments().getString(ARG_PARAM3);
mParam4=getArguments().getString(ARG_PARAM4);
}
if(savedInstanceState==null){
Fragment MutualFundFragment=new Fragment();
getFragmentManager().beginTransaction().
add(R.id.fragment_mutual_funds,MutualFundFragment,
"mutual_fund_tag").commit();
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view=inflater.inflate(R.layout.fragment_mutual_funds, container, false);
mBFLabel=view.findViewById(R.id.fund_name_bf);
mBFDefintion=view.findViewById(R.id.fund_definition_bf);
mBFCurrentNAV=view.findViewById(R.id.current_nav_bf);
mBFCurrentReturn=view.findViewById(R.id.current_return_bf);
mBFLabel.setText(mParam1);
mBFDefintion.setText(mParam2);
mGFLabel=view.findViewById(R.id.fund_name_gf);
mGFDefinition=view.findViewById(R.id.fund_definition_gf);
mGFCurrentNAV=view.findViewById(R.id.current_nav_gf);
mGFCurrentReturn=view.findViewById(R.id.current_return_gf);
mGFLabel.setText(mParam3);
mGFDefinition.setText(mParam4);
return inflater.inflate(R.layout.fragment_mutual_funds, container, false);
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
//Change the texts of Balanced Fund
public void changeBFTexts(FundMaster fm){
mBFLabel.setText(fm.getFundName());
mBFDefintion.setText(fm.getFundDefinition());
}
//Change the texts of Growth Fund
public void changeGFTexts(FundMaster fm){
mGFLabel.setText(fm.getFundName());
mGFDefinition.setText(fm.getFundDefinition());
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
Here is my Fragment Layout
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
tools:context=".MutualFunds"
android:id="#+id/fragment_mutual_funds">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/fund_name_bf"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="28dp"
android:text="#string/mutualfundfrag_iclbf_title"
android:textAppearance="#style/TextAppearance.AppCompat.Large"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/fund_definition_bf"
android:layout_width="319dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="8dp"
android:text="#string/mutualfundfrag_iclbf_definition"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/fund_name_bf" />
<TextView
android:id="#+id/current_nav_bf"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="12dp"
android:text="#string/mutualfundfrag_iclbf_current_nav"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/fund_definition_bf" />
<TextView
android:id="#+id/current_return_bf"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="12dp"
android:text="#string/mutualfundfrag_iclbf_current_return"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/current_nav_bf" />
<TextView
android:id="#+id/fund_performance_bf"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="12dp"
android:text="#string/mutualfundfrag_iclbf_fund_performance"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/current_return_bf" />
<TextView
android:id="#+id/fund_name_gf"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="28dp"
android:text="#string/mutualfundfrag_bcbiclgf_title"
android:textAppearance="#style/TextAppearance.AppCompat.Large"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/fund_performance_bf" />
<TextView
android:id="#+id/fund_definition_gf"
android:layout_width="315dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="12dp"
android:text="#string/mutualfundfrag_bcbiclgf_definition"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/fund_name_gf" />
<TextView
android:id="#+id/current_nav_gf"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="12dp"
android:text="#string/mutualfundfrag_iclbf_current_nav"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/fund_definition_gf" />
<TextView
android:id="#+id/current_return_gf"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="12dp"
android:text="#string/mutualfundfrag_iclbf_current_return"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/current_nav_gf" />
<TextView
android:id="#+id/fund_performance_gf"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="12dp"
android:text="#string/mutualfundfrag_iclbf_fund_performance"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/current_return_gf" />
</android.support.constraint.ConstraintLayout>
</FrameLayout>
Here is the parent activity where the async task is there and the fragment is going to replaced:
super.onPostExecute(result);
if (pd.isShowing()){
pd.dismiss();
}
try {
JSONArray resultJsonArray = new JSONArray(result);
ArrayList<FundMaster> fundsData=new ArrayList<FundMaster>();
for(int i=0;i<resultJsonArray.length();i++){
JSONObject jsonObject= (JSONObject) resultJsonArray.get(i);
fundsData.add(new FundMaster(Integer.valueOf(jsonObject.get("f_id").toString()),
Integer.valueOf(jsonObject.get("fund_id").toString()),
jsonObject.get("fund_name").toString(),
jsonObject.get("fund_definition").toString(),
jsonObject.get("fund_date").toString()));
}
for(FundMaster fm:fundsData){
Log.d("Fund Name",fm.getFundName());
Log.d("Fund Launch Date",fm.getFundLaunchDate());
//MutualFunds mf=new MutualFunds();
//View view=fragment.getView();
if(mutualFundFragment!=null) {
if (fm.getFundId() == 1) {
mutualFundFragment.changeBFTexts(fm);
} else if (fm.getFundId() == 2) {
mutualFundFragment.changeGFTexts(fm);
}
} else{
Log.e("Message Error","Error");
}
changefrag(mutualFundFragment);
}
} catch (JSONException e){
Log.e("JSON Error","JSON problem");
}
}
}
public void changefrag(android.support.v4.app.Fragment frag) {
FragmentManager manager = getSupportFragmentManager();
if (!manager.beginTransaction().isEmpty()) {
manager.beginTransaction().detach(frag);
}
manager.beginTransaction()
.replace(R.id.fragment_mutual_funds, frag).commit();
}
As far I understand, Static Fragment cannot be replaced. Can anyone suggest me what should I do in this case? Thanks in advance.
Related
UPDATES
I added more java files just in case you find them helpful. I figured that I may need to write codes to connect between MainActivity.java and my fragments, but the codes I followed from several YouTube videos do not work. I would be greatly appreciated if you can write me a line of code to connect the fragment.
END OF UPDATES
Whenever I try to add functions in my fragment file, it does not work. I think I may miss some codes in MainActivity.java, but I have no idea what to add to make my fragment's java files work.
Here is my fragment's java file (I did not touch anything but added a simple function to show a check mark when a button is clicked):
package com.example.dailybible3;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
/**
* A simple {#link Fragment} subclass.
* Use the {#link FragmentBible#newInstance} factory method to
* create an instance of this fragment.
*/
public class FragmentBible extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
public FragmentBible() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment fragment_bible.
*/
// TODO: Rename and change types and number of parameters
public static FragmentBible newInstance(String param1, String param2) {
FragmentBible fragment = new FragmentBible();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_bible, container, false);
Button btn_complete = (Button) view.findViewById(R.id.complete_button);
btn_complete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ImageView check_mark = (ImageView) view.findViewById(R.id.check_mark);
int visibility = check_mark.getVisibility();
if(visibility == View.VISIBLE)
{
check_mark.setVisibility(View.INVISIBLE);
}
else
{
check_mark.setVisibility(View.VISIBLE);
}
}
});
return view;
}
}
Just in case, here is my xml file as well:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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=".FragmentBible"
android:theme="#style/FontStyle">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorPrimary"
android:orientation="vertical">
<TextView
android:id="#+id/white_background_round"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="10dp"
android:background="#drawable/white_background_round" />
<RelativeLayout
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/white_background_round"
android:layout_centerHorizontal="true"
android:layout_marginTop="15dp">
<TextView
android:id="#+id/title_string"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/tab_text_2"
android:textColor="#color/colorPrimary"
android:textSize="45sp"
android:textStyle="bold"/>
<ImageView
android:id="#+id/title_image"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_alignTop="#+id/title_string"
android:layout_alignBottom="#+id/title_string"
android:layout_marginLeft="20dp"
android:layout_toEndOf="#+id/title_string"
android:background="#drawable/ic_bible_english" />
</RelativeLayout>
<ImageView
android:id="#+id/button_background"
android:layout_width="wrap_content"
android:layout_marginTop="10dp"
android:layout_height="30dp"
android:layout_alignStart="#+id/white_background_round"
android:layout_alignEnd="#+id/white_background_round"
android:layout_marginRight="60dp"
android:layout_marginLeft="60dp"
android:layout_below="#+id/title"
android:background="#drawable/light_background_round_english" />
<Button
android:id="#+id/niv"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_alignTop="#+id/button_background"
android:layout_alignStart="#+id/button_background"
android:layout_alignBottom="#+id/button_background"
android:layout_toStartOf="#+id/centerline"
android:text="NIV"
android:textColor="#color/colorPrimary"
android:textStyle="bold"
android:background="#android:color/transparent"/>
<Button
android:id="#+id/kjv"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_alignTop="#+id/button_background"
android:layout_alignEnd="#+id/button_background"
android:layout_alignBottom="#+id/button_background"
android:layout_toEndOf="#+id/centerline"
android:text="KJV"
android:textColor="#color/colorPrimary"
android:textStyle="bold"
android:background="#android:color/transparent"/>
<TextView
android:id="#+id/centerline"
android:layout_width="1dp"
android:layout_height="10dp"
android:layout_alignBottom="#+id/button_background"
android:layout_centerHorizontal="true"
android:layout_below="#+id/title"
android:background="#color/colorPrimary"
android:layout_margin="5dp"
android:layout_alignTop="#+id/button_background"
android:elevation="10dp"/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/complete_button"
android:layout_below="#+id/button_background"
android:layout_alignStart="#+id/white_background_round"
android:layout_alignEnd="#+id/white_background_round"
android:layout_marginStart="20dp"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/subtitle1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Leviticus 2"
android:textColor="#color/colorPrimaryLight"
android:textSize="25sp"
android:textStyle="bold"/>
<TextView
android:id="#+id/subtitle_text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/subtitle1"
android:layout_alignStart="#+id/subtitle1"
android:layout_marginEnd="20dp"
android:text="1) When anyone brings a grain offering to the Lord, their offering is to be of the finest flour. They are to pour olive oil on it, put incense on it 2) and take it to Aaron’s sons the priests. The priest shall take a handful of the flour and oil, together with all the incense, and burn this as a memorial portion on the altar, a food offering, an aroma pleasing to the Lord."
android:textColor="#color/colorPrimary"
android:textSize="15sp"
android:textStyle="bold" />
<TextView
android:id="#+id/subtitle2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/subtitle_text1"
android:text="Leviticus 2"
android:textColor="#color/colorPrimaryLight"
android:textSize="25sp"
android:textStyle="bold"/>
<TextView
android:id="#+id/subtitle_text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/subtitle2"
android:layout_alignStart="#+id/subtitle2"
android:layout_marginEnd="20dp"
android:text="1) When anyone brings a grain offering to the Lord, their offering is to be of the finest flour. They are to pour olive oil on it, put incense on it 2) and take it to Aaron’s sons the priests. The priest shall take a handful of the flour and oil, together with all the incense, and burn this as a memorial portion on the altar, a food offering, an aroma pleasing to the Lord."
android:textColor="#color/colorPrimary"
android:textSize="15sp"
android:textStyle="bold"/>
<TextView
android:id="#+id/subtitle3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/subtitle_text2"
android:text="Leviticus 2"
android:textColor="#color/colorPrimaryLight"
android:textSize="25sp"
android:textStyle="bold" />
<TextView
android:id="#+id/subtitle_text3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/subtitle3"
android:layout_alignStart="#+id/subtitle3"
android:layout_marginEnd="20dp"
android:text="1) When anyone brings a grain offering to the Lord, their offering is to be of the finest flour. They are to pour olive oil on it, put incense on it 2) and take it to Aaron’s sons the priests. The priest shall take a handful of the flour and oil, together with all the incense, and burn this as a memorial portion on the altar, a food offering, an aroma pleasing to the Lord."
android:textColor="#color/colorPrimary"
android:textSize="15sp"
android:textStyle="bold"/>
</RelativeLayout>
</ScrollView>
<TextView
android:id="#+id/complete_button_background"
android:layout_width="wrap_content"
android:layout_height="60sp"
android:layout_alignBottom="#+id/white_background_round"
android:layout_alignRight="#+id/white_background_round"
android:layout_alignLeft="#+id/white_background_round"
android:layout_marginRight="75dp"
android:layout_marginLeft="75sp"
android:layout_marginBottom="20sp"
android:background="#drawable/light_background_round_english" />
<ImageView
android:id="#+id/check_mark"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/complete_button"
android:layout_alignLeft="#+id/complete_button"
android:layout_alignRight="#+id/complete_button"
android:layout_alignTop="#+id/complete_button"
android:elevation="10dp"
android:visibility="invisible"
android:src="#drawable/ic_check_english"/>
<TextView
android:id="#+id/complete_button_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Complete"
android:layout_alignTop="#+id/complete_button_background"
android:layout_alignLeft="#+id/complete_button_background"
android:layout_alignBottom="#+id/complete_button_background"
android:layout_marginLeft="10sp"
android:layout_marginTop="10sp"
android:layout_marginBottom="10sp"
android:gravity="center"
android:textSize="30sp"
android:textColor="#color/colorPrimary"
android:textStyle="bold"/>
<Button
android:id="#+id/complete_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="#+id/complete_button_background"
android:layout_alignBottom="#+id/complete_button_background"
android:layout_alignTop="#+id/complete_button_background"
android:layout_marginTop="7sp"
android:layout_marginBottom="7sp"
android:layout_marginRight="10sp"
android:layout_marginLeft="10sp"
android:layout_toEndOf="#+id/complete_button_text"
android:background="#drawable/white_button_round" />
</RelativeLayout>
</FrameLayout>
And here is MainActivity.java:
package com.example.dailybible3;
import android.os.Bundle;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.tabs.TabLayout;
import androidx.viewpager.widget.ViewPager;
import androidx.appcompat.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import com.example.dailybible3.ui.main.SectionsPagerAdapter;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager());
ViewPager viewPager = findViewById(R.id.view_pager);
viewPager.setAdapter(sectionsPagerAdapter);
TabLayout tabs = findViewById(R.id.tabs);
tabs.setupWithViewPager(viewPager);
}
}
Also, here is the adapter:
package com.example.dailybible3.ui.main;
import android.content.Context;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import com.example.dailybible3.R;
/**
* A [FragmentPagerAdapter] that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
#StringRes
private static final int[] TAB_TITLES = new int[]{R.string.tab_text_1, R.string.tab_text_2, R.string.tab_text_3, R.string.tab_text_4, R.string.tab_text_5};
private final Context mContext;
public SectionsPagerAdapter(Context context, FragmentManager fm) {
super(fm);
mContext = context;
}
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a PlaceholderFragment (defined as a static inner class below).
return PlaceholderFragment.newInstance(position + 1);
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
return mContext.getResources().getString(TAB_TITLES[position]);
}
#Override
public int getCount() {
// Show 5 total pages.
return 5;
}
}
And here is PlaceHolderFragment.java:
package com.example.dailybible3.ui.main;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import com.example.dailybible3.R;
/**
* A placeholder fragment containing a simple view.
*/
public class PlaceholderFragment extends Fragment {
private static final String ARG_SECTION_NUMBER = "section_number";
private PageViewModel pageViewModel;
public static PlaceholderFragment newInstance(int index) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle bundle = new Bundle();
bundle.putInt(ARG_SECTION_NUMBER, index);
fragment.setArguments(bundle);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
pageViewModel = ViewModelProviders.of(this).get(PageViewModel.class);
int index = 1;
if (getArguments() != null) {
index = getArguments().getInt(ARG_SECTION_NUMBER);
}
pageViewModel.setIndex(index);
}
#Override
public View onCreateView(
#NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = null;
switch(getArguments().getInt(ARG_SECTION_NUMBER))
{
case 1:
root = inflater.inflate(R.layout.fragment_main, container, false);
break;
case 2:
root = inflater.inflate(R.layout.fragment_bible, container, false);
break;
case 3:
root = inflater.inflate(R.layout.fragment_notes, container, false);
break;
case 4:
root = inflater.inflate(R.layout.fragment_alarm, container, false);
break;
case 5:
root = inflater.inflate(R.layout.fragment_records, container, false);
break;
}
return root;
}
}
And here is the PageViewModel.java (which I am not quite sure why it is needed):
package com.example.dailybible3.ui.main;
import androidx.arch.core.util.Function;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Transformations;
import androidx.lifecycle.ViewModel;
public class PageViewModel extends ViewModel {
private MutableLiveData<Integer> mIndex = new MutableLiveData<>();
private LiveData<String> mText = Transformations.map(mIndex, new Function<Integer, String>() {
#Override
public String apply(Integer input) {
return "Hello world from section: " + input;
}
});
public void setIndex(int index) {
mIndex.setValue(index);
}
public LiveData<String> getText() {
return mText;
}
}
Any help is greatly appreciated!
enter image description hereI'm totally new in android studio and java.
I created one bottomNavigation for my app and I used 3 fragments and it's totally fine and working.
but now I want to add one seekBar and click listener on one of my fragments but I couldn't do it.
my question is in which life cycle view or function I have to add this seek bar click listener?
I want to add this code as a seekbar listener
seekBar.findViewById(R.id.seekBar);
textView.findViewById(R.id.textView3);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
textView.setText(progress+"/100");
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
**View**
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:id="#+id/f2"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SecondFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:orientation="vertical"
android:padding="10dp"
android:gravity="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="#string/diary_pgae_sleep" />
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:layout_marginTop="10dp"
android:gravity="center"
android:text="0/24" />
<SeekBar
android:id="#+id/seekBar"
style="#style/AppTheme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:layout_weight="1"
android:max="24"
android:progress="0"
android:progressDrawable="#drawable/track1"
android:thumb="#drawable/thumb"
android:thumbTint="#color/colorPrimaryDark"
android:indeterminate="false"/>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
**Code**
package com.example.myapplication;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SeekBar;
import android.widget.TextView;
/**
* A simple {#link Fragment} subclass.
* Use the {#link SecondFragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class SecondFragment extends Fragment {
SeekBar seekBar;
TextView textView;
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
public SecondFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment SecondFragment.
*/
// TODO: Rename and change types and number of parameters
public static SecondFragment newInstance(String param1, String param2) {
SecondFragment fragment = new SecondFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_second, container, false);
}
}
For this, you actually need separate java files that, in the class declaration, extends 'Fragment'. This is a really good youtube video for it:
https://www.youtube.com/watch?v=bNpWGI_hGGg
Hope this helps.
I have a button in an fragment that when I clicked on it nothing happens at all
this is the java code of the fragment:
public class HomeFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
EditText etAddPost;
Button addPostImage;
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef;
public HomeFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment HomeFragment.
*/
// TODO: Rename and change types and number of parameters
public static HomeFragment newInstance(String param1, String param2) {
HomeFragment fragment = new HomeFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
database = FirebaseDatabase.getInstance();
myRef = database.getReference("posts");;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_home, container, false);
etAddPost =rootView.findViewById(R.id.etAddPost);
addPostImage = rootView.findViewById(R.id.addPostBtn);
addPostImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(getActivity(), "Clicked", Toast.LENGTH_SHORT).show();
String postText = etAddPost.getText().toString();
if(TextUtils.isEmpty(postText)){
etAddPost.setError("لا يمكنك ترك هذا الحقل فارغا");
}
else {
Map<String, String> map = new HashMap<>();
map.put("postContent", postText);
myRef.push().setValue(map);
etAddPost.setText("");
}
}
}); return rootView;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
"http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
and this is my XML code :
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
android:background="#color/color3"
tools:context="com.mk.playAndLearn.fragment.HomeFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/white"
android:orientation="horizontal">
<Button
android:id="#+id/addPostBtn"
android:layout_width="0dp"
android:layout_height="30dp"
android:layout_weight="1"
android:layout_margin="5dp"
android:background="#drawable/send"
android:layout_marginRight="5dp"/>
<EditText
android:layout_margin="5dp"
android:id="#+id/etAddPost"
android:layout_width="0dp"
android:gravity="right"
android:layout_height="wrap_content"
android:layout_weight="7"
android:hint="ماذا يخطر في بالك؟"
android:paddingRight="10dp"/>
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</FrameLayout>
I have tried a lot to solve this problem but I couldn't but I am feeling that solving the problem is easy so I hope that any one helps me to solve this problem I tried to change the button type and use ImageButton instead but that doesn't solve the problem
I think you've problems with xml layout. Your recyclerview laying over linear layout. Change the layout as below
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
android:background="#color/color3"
tools:context="com.mk.playAndLearn.fragment.HomeFragment">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/white"
android:orientation="horizontal">
<Button
android:id="#+id/addPostBtn"
android:layout_width="0dp"
android:layout_height="30dp"
android:layout_weight="1"
android:layout_margin="5dp"
android:background="#drawable/send"
android:layout_marginRight="5dp"/>
<EditText
android:layout_margin="5dp"
android:id="#+id/etAddPost"
android:layout_width="0dp"
android:gravity="right"
android:layout_height="wrap_content"
android:layout_weight="7"
android:hint="ماذا يخطر في بالك؟"
android:paddingRight="10dp"/>
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</FrameLayout>
I'm having an issue in the Android app that I'm developing where a the text in a Fragment containing a TextView covers the bottom navigation if the text is too long. The issue looks like this:
TextView blocking bottom navigation
Here's the code for the Fragment:
package com.example.xxxxxx.loremipsum;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.constraint.ConstraintLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
/**
* A simple {#link Fragment} subclass.
* Activities that contain this fragment must implement the
* {#link LessonFragment.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {#link LessonFragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class LessonFragment extends Fragment
{
private String lessonContent;
private OnFragmentInteractionListener mListener;
TextView lesson;
private int lessonID;
private boolean culture;
public LessonFragment()
{
}
#SuppressLint("ValidFragment")
public LessonFragment(int lessonID)
{
this.lessonID = lessonID;
culture = false;
}
#SuppressLint("ValidFragment")
public LessonFragment(int lessonID, int i)
{
this.lessonID = lessonID;
culture = true;
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment LessonFragment.
*/
public static LessonFragment newInstance(String param1, String param2)
{
return null;
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if (getArguments() != null)
{
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_lesson, container, false);
ConstraintLayout.LayoutParams layoutParams = new ConstraintLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
view.setLayoutParams(layoutParams);
Button button = (Button) view.findViewById(R.id.backButton);
button.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
if(!culture)
{
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
GrammarFragment GF = new GrammarFragment();
fragmentTransaction.replace(R.id.container, GF);
fragmentTransaction.commit();
}
else
{
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
CultureFragment CF = new CultureFragment();
fragmentTransaction.replace(R.id.container, CF);
fragmentTransaction.commit();
}
}
});
lesson = (TextView) view.findViewById(R.id.grammarContent);
String[] lessons;
if(!culture)
lessons = getActivity().getResources().getStringArray(R.array.lessons);
else
lessons = getActivity().getResources().getStringArray(R.array.cultureLessons);
lessonContent = lessons[lessonID];
lesson.setText(lessonContent);
return view;
}
#Override
public void onAttach(Context context)
{
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener)
{
mListener = (OnFragmentInteractionListener) context;
}
else
{
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach()
{
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener
{
void onBackClickCulture();
}
}
Here's the XML for the Fragment:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="com.example.xxxxxx.loremipsum.LessonFragment">
<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/grammarContent"
android:textSize="18sp"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Back"
android:id="#+id/backButton"
tools:ignore="OnClick" />
</LinearLayout>
</ScrollView>
Finally, here's the XML for my MainActivity, where the Fragment is being added:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.xxxxxx.loremipsum.MainActivity">
<android.support.design.widget.BottomNavigationView
android:id="#+id/navigation"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="0dp"
android:layout_marginStart="0dp"
android:background="?android:attr/windowBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="#menu/navigation" />
</android.support.constraint.ConstraintLayout>
EDIT: Here's a screenshot of a further issue:
Here's the bug I'm having
Please add one more layout in your MainActivity xml portion. And you also change in MainActivity R.id.fl_main with R.id.container
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.buttonnavifragment.MainActivity">
<FrameLayout
android:id="#+id/fl_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="#dimen/activity_horizontal_margin"
android:layout_marginStart="#dimen/activity_horizontal_margin"
android:layout_marginTop="#dimen/activity_vertical_margin"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.design.widget.BottomNavigationView
android:id="#+id/navigation"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="0dp"
android:layout_marginStart="0dp"
android:background="?android:attr/windowBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="#menu/navigation" />
</android.support.constraint.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout>
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<android.support.design.widget.BottomNavigationView
/>
</LinearLayout>
Your container should be an View which should be above BottomNavigationView. That's why you are having these conflicts. Because you just attach Fragment on parent view.
Set a background always to Fragment parent element. Because Fragment inflate on top of other to maintain stack.
I would like to know how to implement a tabbed activity( 4 fragments) with recycler and cardview that connect to a firebase DB to pull data.
-Do I have to create an adapter for each fragment or same adapter but each fragment will filter what data it requires?
-Do I have to call getInstance and reference Firebase DB from main Activity?
I'm completely new to recyclerView, please give me every possible details.
-For the cardview, an object will be created called "property", 2 textview and 1 imageview. How this will fit into the whole code, I mean the property class and its instance.
-Can I store the image that will be used in the cardview on Firebase Storage? If so how to query them?
Here's the code
package com.realty.drake.kunuk;
import android.support.design.widget.TabLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
public class MainActivity extends AppCompatActivity {
/**
* The {#link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {#link FragmentPagerAdapter} derivative, which will keep every
* loaded fragment in memory. If this becomes too memory intensive, it
* may be best to switch to a
* {#link android.support.v4.app.FragmentStatePagerAdapter}.
*/
private SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {#link ViewPager} that will host the section contents.
*/
private ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.d("debugg", "OnCreate started");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Log.d("DEBUGG","getItem called" );
//Returning the current tab
switch (position) {
case 0:
Tab1Buy tab1 = new Tab1Buy();
return tab1;
case 1:
Tab2Rent tab2 = new Tab2Rent();
return tab2;
case 2:
Tab3Lot tab3 = new Tab3Lot();
return tab3;
case 3:
Tab4Saved tab4 = new Tab4Saved();
return tab4;
default:
return null;
}
}
#Override
public int getCount() {
// Show 4 total pages.
return 4;
}
#Override
public CharSequence getPageTitle(int position){
Log.d("Debugg", "getPageTitle: Executed");
switch (position) {
case 0:
return "BUY";
case 1:
return "RENT";
case 2:
return "LOT";
case 3:
return "SAVED";
}
return null;
}
}
}
package com.realty.drake.kunuk;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* Created by drake on 4/11/18.
*/
public class Tab1Buy extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.tab1buy, container, false);
return rootView;
}
}
package com.realty.drake.kunuk;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* Created by drake on 4/11/18.
*/
public class Tab2Rent extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.tab2rent, container, false);
return rootView;
}
}
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.realty.drake.kunuk.MainActivity">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="#dimen/appbar_padding_top"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_weight="1"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/AppTheme.PopupOverlay"
app:title="#string/app_name">
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMaxWidth="0dp"
app:tabGravity="fill"
app:tabMode="fixed">
<android.support.design.widget.TabItem
android:id="#+id/tabItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/tab_text_1" />
<android.support.design.widget.TabItem
android:id="#+id/tabItem2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/tab_text_2" />
<android.support.design.widget.TabItem
android:id="#+id/tabItem3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/tab_text_3" />
</android.support.design.widget.TabLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="#dimen/fab_margin"
app:srcCompat="#android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#dfdfdf"
android:orientation="vertical">
<!-- TODO Add white icon -->
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/tools"
android:id="#+id/property"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:cardUseCompatPadding="true"
card_view:cardCornerRadius="4dp"
card_view:cardElevation="4dp">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="290dp"
android:orientation="vertical">
<ImageView
android:id="#+id/post_image"
android:contentDescription="#string/property"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="71dp"
android:scaleType="centerCrop"
android:src="#drawable/house1"
app:layout_constraintBottom_toTopOf="#+id/number_bedroom"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/post_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginStart="5dp"
android:layout_marginTop="8dp"
android:text="55,000$"
android:textColor="#color/colorPrimary"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.79" />
<TextView
android:id="#+id/post_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginStart="5dp"
android:layout_marginTop="1dp"
android:text="23,Rue Duvivier-hall, Les Cayes, "
android:textColor="#737373"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/post_title"
app:layout_constraintVertical_bias="0.0" />
<ImageView
android:id="#+id/bathroom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginStart="100dp"
android:layout_marginTop="2dp"
android:background="#ff9100"
android:src="#drawable/bathtub"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.976" />
<ImageView
android:id="#+id/bedroom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginStart="25dp"
android:layout_marginTop="2dp"
android:background="#ff9100"
android:src="#drawable/bedroom"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.976" />
<TextView
android:id="#+id/number_bathroom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:text="2"
android:textColor="#ff9100"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="#+id/bathroom"
app:layout_constraintEnd_toStartOf="#+id/bathroom" />
<TextView
android:id="#+id/number_bedroom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:text="3"
android:textColor="#ff9100"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="#+id/bedroom"
app:layout_constraintEnd_toStartOf="#+id/bedroom" />
<TextView
android:id="#+id/number_garage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:text="1"
android:textColor="#ff9100"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="#+id/garage"
app:layout_constraintEnd_toStartOf="#+id/garage" />
<ImageView
android:id="#+id/garage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginStart="175dp"
android:layout_marginTop="2dp"
android:background="#ff9100"
android:src="#drawable/garage"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.976" />
</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<!--TODO add recyclerView layout-->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/rv_items">
</android.support.v7.widget.RecyclerView>
</FrameLayout>
Thanks for your help
-Do I have to create an adapter for each fragment or same adapter but each fragment will filter what data it requires?
A: I have each fragment get their own reference to the firebase database, each one querying a child. In the firebase database, look at image, each Fragment call one child: Buy, Lot, Rent..
-Do I have to call getInstance and reference Firebase DB from main Activity? I'm completely new to recyclerView, please give me every possible details.
A: I call the getIntance in each fragment instead,
public class Tab1Buy extends Fragment {
private DatabaseReference propertyRef;
private RecyclerView mPropertyRecyclerView;
FirebaseRecyclerAdapter<Property, PropertyViewHolder> mPropertyAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.property_tab, container, false);
mPropertyRecyclerView = rootView.findViewById(R.id.property_recyclerView);
return rootView;
}
//TODO Check internet and display error msg if internet down
#Override
public void onViewCreated(final View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mPropertyRecyclerView.hasFixedSize();
mPropertyRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
final ProgressBar progressBar = view.findViewById(R.id.progressBar);
progressBar.setVisibility(View.VISIBLE);
propertyRef = FirebaseDatabase.getInstance()
.getReference()
.child("Buy");
propertyRef.keepSynced(true);
// keyQuery - the Firebase location containing the list of keys to be found in dataRef
//Query personQuery = propertyRef.orderByKey();
FirebaseRecyclerOptions<Property> options =
new FirebaseRecyclerOptions.Builder<Property>()
.setQuery(propertyRef, Property.class)
.build();
mPropertyAdapter = new FirebaseRecyclerAdapter<Property, PropertyViewHolder>(options) {
#Override
// Bind the Property object to the ViewHolder PropertyHolder
public void onBindViewHolder(#NonNull PropertyViewHolder holder,
final int position, #NonNull final Property model) {
holder.setPrice(model.getPrice());
holder.setAddress(model.getAddress());
holder.setNumberOfBed(model.getNumberOfBed());
holder.setNumberOfBath(model.getNumberOfBath());
holder.setNumberOfCar(model.getNumberOfCar());
holder.setPropertyImage(model.getPropertyImage());
//This Intent send Parcelable from Property to PropertyDetail
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
getActivity().startActivity(new Intent(getActivity(), PropertyDetail.class)
.putExtra("Property", model));
}
});
}
#Override
public PropertyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// Create a new instance of the ViewHolder, in this case we are using a custom
// layout called R.layout.property_card for each item
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.property_card, parent, false);
return new PropertyViewHolder(view);
}
#Override
public void onDataChanged() {
// Called each time there is a new data snapshot. You may want to use this method
// to hide a loading spinner or check for the "no documents" state and update your UI.
// ...
progressBar.setVisibility(View.GONE);
}
//TODO Implement onError
#Override
public void onError(#NonNull DatabaseError e) {
// Called when there is an error getting data. You may want to update
// your UI to display an error message to the user.
// ...
progressBar.setVisibility(View.GONE);
Toast.makeText(getActivity(), "DatabaseError", Toast.LENGTH_SHORT).show();
}
};
mPropertyRecyclerView.setAdapter(mPropertyAdapter);
}
#Override
public void onStart() {
super.onStart();
mPropertyAdapter.startListening();
}
#Override
public void onStop() {
super.onStop();
mPropertyAdapter.stopListening();
}
public class PropertyViewHolder extends RecyclerView.ViewHolder {
View mView;
public PropertyViewHolder(View itemView) {
super(itemView);
mView = itemView;
}
public void setPrice(int price) {
String currencyPrice = NumberFormat //Format the price variable in currency form
.getCurrencyInstance(Locale.US)
.format(price);
TextView Price = mView.findViewById(R.id.post_price);
Price.setText(currencyPrice);
}
public void setAddress(String address){
TextView Address = mView.findViewById(R.id.post_address);
Address.setText(String.valueOf(address));
}
public void setNumberOfBed(int numberOfBed){
TextView NumberOfBed = mView.findViewById(R.id.post_bedroom);
NumberOfBed.setText(String.valueOf(numberOfBed));
}
public void setNumberOfBath(int numberOfBath){
TextView NumberOfBath = mView.findViewById(R.id.post_bathroom);
NumberOfBath.setText(String.valueOf(numberOfBath));
}
public void setNumberOfCar(int numberOfCar) {
TextView NumberOfCar = mView.findViewById(R.id.post_garage);
NumberOfCar.setText(String.valueOf(numberOfCar));
}
public void setPropertyImage(String propertyImage){
ImageView imageView = mView.findViewById(R.id.post_propertyImage);
//take one long string containing multiple url in and parse it
String propertyImageArray[] = propertyImage.split(",");
//Loading circle for placeholder, ColorAccent has been used
CircularProgressDrawable progressDrawable =
new CircularProgressDrawable(getContext());
progressDrawable.setStrokeWidth(5f);
progressDrawable.setCenterRadius(30f);
progressDrawable.setColorSchemeColors(Color.argb(1,255,145,0));
progressDrawable.start();
// Download directly from StorageReference using Glide
// (See MyAppGlideModule for Loader registration)
GlideApp.with(getContext())
.load(propertyImageArray[0])
.placeholder(progressDrawable)
.fitCenter()
.into(imageView);
}
}
}
-For the cardview, an object will be created called "property", 2 textview and 1 imageview. How this will fit into the whole code, I mean the property class and its instance.
A: Create a new instance of the ViewHolder, in this case we are using a custom layout called R.layout.property_card for each item. Look at the code above, specifically at that line public PropertyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
-Can I store the image that will be used in the cardview on Firebase Storage? If so how to query them?
A: yes I stored image in Firebase Storage,then I use their generated url to pass in Glide method. look at the code above.
I only show for the first fragment because they all look similar, except the child reference in the firebase differ.