How to switch between two viewpages on button click? - android

I have used a Viewpager for horiantal swiping of images which are present inside drawable folder i have used http://idroidsoftwareinc.blogspot.in/2013/06/android-viewpager-swipe-images-using.html this link now i have another int array of image for which i have used the same code now i just want to switch between another viewpager on button click so that I can access the images(for Swiping) from that viewPager. PLEASE HELP ME? I am stuck...
I have referred this links
How to get several ViewPagers into a ScrollView?
Add multiple images and text to each ViewPager slide

One way of doing this is hiding the first ViewPager and showing the second one.
From what you are saying it seems that you have the two view pagers in the same layout, something like this (I am giving a simplified version just to illustrate!):
main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<android.support.v4.view.ViewPager
android:id="#+id/view_pager1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.v4.view.ViewPager
android:id="#+id/view_pager2"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
In your Activity you need to get a reference to these view pagers, which I assume you have already. And then in the OnClickListener of your button change the visibility of the view pagers:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); // This is the name of you layout file
final ViewPager viewPager1 = (ViewPager) findViewById(R.id.view_pager1);
final ViewPager viewPager2 = (ViewPager) findViewById(R.id.view_pager2);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
viewPager1.setVisibility(View.GONE);
viewPager2.setVisibility(View.VISIBLE);
}
});
// ...
}

Related

Fragment Question, where to build buttons etc

I am using fragments to update a text view I have so when the person clicks a button the text view moves on to the next question. I'm not sure if I am doing the correct work in one fragment instead of the other. My current screen looks like this:
I will probably have to add some more buttons/widgets to this but should I be adding it into the XML for the fragment or the fragment container?
Here is XML for fragment actions:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/fragment_question_layout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp"
tools:context=".FragmentActions"
>
<!-- this is where fragments will be shown-->
<FrameLayout
android:id="#+id/question_container1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="4"
android:scaleType="centerInside" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="#+id/questions_yes1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="#string/yes" />
<Button
android:id="#+id/questions_no1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="#string/no" />
</LinearLayout>
</LinearLayout>
And here is the fragment details:
<?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:id="#+id/button_layout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
tools:context=".FragmentDetails">
<!--Blank Fragment Layout-->
<TextView
android:id="#+id/questions_text_view1"
android:layout_width="match_parent"
android:layout_height="91dp"
android:gravity="center"
android:textAlignment="center"
/>
</FrameLayout>
Updated FragmentDetails
public class FragmentDetails extends Fragment {
private final String TAG = getClass().getSimpleName();
private List<Integer> mQuestionIds;
private int mListIndex;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//Inflate the fragment layout
View rootView = inflater.inflate(R.layout.fragment_details, container, false);
//Get a reference to the textView in the fragment layout
final TextView textView = (TextView) rootView.findViewById(R.id.questions_text_view1);
if (mQuestionIds != null) {
textView.setText(mQuestionIds.get(mListIndex));
//Increment the position in the question lisy as long as index is less than list length
if (mListIndex < mQuestionIds.size() - 1) {
mListIndex++;
setmQuestionIds(QuestionList.getQuestions());
setmListIndex(mListIndex);
} else {
//end of questions reached
textView.setText("End of questions");
}
//Set the text resource to display the list item at that stored index
textView.setText(mQuestionIds.get(mListIndex));
}
else {
//Log message that list is null
Log.d(TAG, "No questions left");
}
//return root view
return rootView;
}
public void setmQuestionIds (List < Integer > mQuestionIds) {
this.mQuestionIds = mQuestionIds;
}
public void setmListIndex ( int mListIndex){
this.mListIndex = mListIndex;
}
}
Fragment Actions activity
public class FragmentActions extends AppCompatActivity {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_actions);
Button yes = findViewById(questions_yes1);
// Only create new fragments when there is no previously saved state
if (savedInstanceState == null) {
//Create Question Fragment
final FragmentDetails fragmentDetails = new FragmentDetails();
fragmentDetails.setmQuestionIds(QuestionList.getQuestions());
yes.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//set the list of question Ids for the head fragent and set the position to the second question
//Fragment manager and transaction to add this fragment
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.question_container1, fragmentDetails)
.commit();
}
});
}
}
}
If your Buttons remain the same while the TextView changes, you may add your Buttons to the fragment container.
Remember that, your fragments will be presented inside the FrameLayout of the fragment container. You gotta keep your Buttons, outside the FrameLayout.
Or if you want to have different Buttons for different fragments (Questions, in your case), you can also add the Buttons to the fragments. But in that case, you gotta add them separately to each of the fragments.
I guess there's no right answer to your question. You could try different approaches.
Maybe you could implement the buttons in the fragment container, as #smmehrab pointed out. I see this as a more difficult solution, because when you click on an item from the container you can manage the views of the container, not the fragment's views. You would get NullPointer if I recall correctly. This happens because the context when the button is clicked in the fragment container is different than the context when clicking from within the fragment. So you should implement an interface on the fragment container that listens to clicks, and the fragment catches the click. You could do this, and I actually am doing it in my current app, but I have no choice.
You could instead use Motion Layout (which extends from Constraint Layout) as the root view of your fragment, instead of CardView. This way you could set all the fragment's views with a flat hierarchy (flat hierarchies improves rendering time, so that's an improvement, and you can use CardView as one child) and set the buttons right there, in the Motion Layout (remember, the motion layout would be the fragment's root view). You could set the click listener right there and implement animations between different textViews.
I'm sure there are plenty of other solutions, take this only as a contribution.
If you're unfamiliar with Motion Layout you can just google it, android official documentation about it is great.

Android - Cycling through Images component

I'm looking for a component like this:
If you have used Tinder, i want something like when you view a profile, how you can cycle through their pictures.
I'm pretty sure i can implement this manually, but was wondering if something already exists, and i don't really know how to look it up.
Thanks!
Edit: Also sorry for the bad title, didn't really know how to name these types of questions.
You can do your own implementation or could use some libraries. For you own implementation I would suggest using either ViewPager passing Views instead of fragments or PageTransformer if you want something more elaborate.
If you prefer libraries, I would recommend InfiniteCycleViewPager, sayyam's carouselview or you can go in a tour here: https://android-arsenal.com/tag/154, there is a lot of libraries with different implementations.
Example of implementation of an image slider using ViewPager:
First create your activity's xml with a ViewPager component:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager 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/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.stackoverflow.imageslider.MainActivity">
</android.support.v4.view.ViewPager>
Then in your activity's onCreate method instantiate the ViewPager and create an adapter for it:
ViewPager viewPager = findViewById(R.id.view_pager);
ViewPagerAdapter adapter = new ViewPagerAdapter(this, imageList);
viewPager.setAdapter(adapter);
In the ViewPagerAdapter class (that should extend PageAdapter), you will control the images overriding the method instantiateItem():
#NonNull
#Override
public Object instantiateItem(#NonNull ViewGroup container, int position) {
ImageView imageView = new ImageView(context);
imageView.setImageDrawable(imageList.get(position));
return imageView;
}
In this example imageList would be an List that is fulfilled somewhere else.
This example is based in a tutorial from codinginflow.com, and you can also take a look there.
Now let's see a simpler implementation, that would do just like you asked, touching the image sides instead of sliding.
Example of simpler implementation:
Create a layout with an ImageView and two buttons overriding it, one for next image on the right and one for previous image in the left:
<?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:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:srcCompat="#tools:sample/backgrounds/scenic" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<Button
android:id="#+id/buttonPrevious"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#android:color/transparent" />
<Button
android:id="#+id/buttonNext"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#android:color/transparent" />
</LinearLayout>
</FrameLayout>
Then set the onClick of each button to get the images from a list and set in the ImageView.
final ImageView imageView = findViewById(R.id.imageView);
Button next = findViewById(R.id.buttonNext);
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
currentPosition ++;
imageView.setImageDrawable(drawableList.get(currentPosition));
}
});
Button previous = findViewById(R.id.buttonPrevious);
previous.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
currentPosition --;
imageView.setImageDrawable(drawableList.get(currentPosition));
}
});
drawableList would be a Drawable that is fulfilled somewhere else. You could also change to a different kind of image list, doesn't matter. current position would be and int that starts at 0.
For PageTransformer I would recommend Bincy Baby's answer and phantomraa's answer.
In case the link gets broken I'll leave Bincy Baby's code here:
viewPagerMusicCategory.setPageTransformer(false, new ViewPager.PageTransformer() {
#Override
public void transformPage(View page, float position) {
Log.e("pos",new Gson().toJson(position));
if (position < -1) {
page.setScaleY(0.7f);
page.setAlpha(1);
} else if (position <= 1) {
float scaleFactor = Math.max(0.7f, 1 - Math.abs(position - 0.14285715f));
page.setScaleX(scaleFactor);
Log.e("scale",new Gson().toJson(scaleFactor));
page.setScaleY(scaleFactor);
page.setAlpha(scaleFactor);
} else {
page.setScaleY(0.7f);
page.setAlpha(1);
}
}
}
);
I think you could also mix PageTransformer with the examples I gave.
The libraries each one already have a good documentation, if not in the android arsenal you can find it in GitHub, and even if I post some code here, if the library closes, gets outdated or something like that, the code will not be useful anymore.

Android: Fragment is added below childview

I have a FrameLayout with a few buttons, and some ImageViews. When I add a fragment, it shows on top of the ImageViews as expected but below the buttons but I don't know why.
I searched through a lot of the SO posts but couldn't find problems similar to mine.
I have a custom onClickListener that adds the fragment
Custom clickListener class:
public void onClick(View v) {
// a context is passed to the listener
// this gets rootview id
int id= ((ViewGroup)((Activity)context).getWindow().getDecorView().findViewById(android.R.id.content)).getChildAt(0).getId();
MyFragment myFragment = new MyFragment();
FragmentTransaction ft = ((Activity) context).getFragmentManager().beginTransaction();
ft.add(id, myFragment, "F1");
ft.commit();
}
The View I am adding the fragment to:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/startscreen"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/gamelogo"
android:id="#+id/logo"
android:scaleType="fitStart"
android:adjustViewBounds="true"
/>
</FrameLayout>
Activity:
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.startmenu);
final FrameLayout r = (FrameLayout) findViewById(R.id.startscreen);
addViews(r);
}
public void addViews(FrameLayout r){
// add some buttons to r
// add custom OnClickListener to one of the buttons
// add some ImageViews
// add animation to one button
}
FrameLayout is designed to block out an area on the screen to display a single item. Generally, FrameLayout should be used to hold a single child view, because it can be difficult to organize child views in a way that's scalable to different screen sizes without the children overlapping each other.
That's from the Docs, did you considered to change the layout?
I figured that I have to add the fragment to the parent of the base FrameLayout. I don't know why I would have to do that though.

How to replace an Android fragment with another fragment inside a ViewPager?

I have a view pager consisting of 4 tabs. Each tab holds its own fragment.
How would I be able to use fragment transaction to replace the fragment in tab 3 with a new fragment?
I've tried a lot of things, but I have not been able to come up with a solution at all. I've tried looking around on google and stackoverflow, but with no success.
I assume that your fragment has a button that is put in the center. By clicking on it, you can change the layout stays under of this button. The content/layout of the first fragment you mentioned should be replaced with wrapperA and the content/layout of the second one should be replaced with wrapperB. I put a simple red background for wrapperA to distinguish it with wrapperB, wrapperB is also green due to the same reason. I hope this is what you want:
public class SwitchingFragment extends Fragment {
Button switchFragsButton;
RelativeLayout wrapperA, wrapperB;
View rootView;
#Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.layout_switch, container, false);
wrapperA = (RelativeLayout) rootView.findViewById(R.id.wrapperA);
wrapperB = (RelativeLayout) rootView.findViewById(R.id.wrapperB);
switchFragsButton = (Button) rootView.findViewById(R.id.switchFragsButton);
switchFragsButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
if (wrapperB.getVisibility() == View.GONE) {
wrapperB.setVisibility(View.VISIBLE);
// There is no need to change visibility of wrapperA since it stays behind when wrapperB is visible.
// wrapperA.setVisibility(View.GONE);
}
else {
wrapperB.setVisibility(View.GONE);
// Again, there is no need.
// wrapperA.setVisibility(View.VISIBLE);
}
}
});
return rootView;
}
}
The layout:
<?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="match_parent"
android:layout_gravity="center"
android:orientation="vertical">
<!-- The content of first fragment should be in "wrapperA". -->
<RelativeLayout
android:id="#+id/wrapperA"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/red"
android:visibility="visible">
</RelativeLayout>
<!-- The content of second fragment should be in "wrapperB". -->
<RelativeLayout
android:id="#+id/wrapperB"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/green"
android:visibility="gone">
</RelativeLayout>
<!-- As I said, I assume that the layout switcher button is stable
and so it should be in front of the switching layouts. -->
<Button
android:id="#+id/switchFragsButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:background="#color/black"
android:text="Switch"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="#color/white"/>
</RelativeLayout>
Alternatively, you can try to change the fragment directly by notifying your FragmentPagerAdapter as described in this link:
Replace fragment with another fragment inside ViewPager

Android Fragment : bug fix explanation

I'm starting using Fragments, and I've done like the API guide but ... of course it'd be too easy ;)
When I launch the app, it crashes. After some research I've found this post Android fragment is not working
and the response of Stephen Wylie seems to correct the things for Ali, but .. I don't get it !
Where should I put the FrameLayout ? The "where_i_want_my_fragment" id... it's whatever I want, right ?
and finally where should I put the Java code ? in my activity (which is displaying 2 fragments by the way) .
Thanks !
Nico
EDIT : Let's just say what I want for design you would understand better I think.
I want a list fragment on left side which display a list of strings, and to the right side I want a fragment displaying info regarding the selected string in the list. And I wanna be able to swip with fingers movements the right side of my app (I dont know if it s better to swipe fragment or whatever.. It's the same layout but filled with differents datas)
Ok I just post my code because I really don't see why it doesn't do anything.
This is my activity_main.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:baselineAligned="false"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/list_frag"
android:name="main.courante.c.DateListFragment"
android:layout_width="fill_parent"
android:layout_height="match_parent" >
</FrameLayout>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fiche_frag"
android:name="main.courante.c.fiche_frag"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent" >
</FrameLayout>
</LinearLayout>
Here is my main activity :
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DateListFragment fragment = new DateListFragment();
getFragmentManager().beginTransaction().add(R.id.list_frag, fragment).commit();
fiche_freg frag2 = new fiche_frag();
getFragmentManager().beginTransaction().add(R.id.fiche_frag,frag2).commit();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
Here is DateListFragment (no onCreateView because it 's automatically generated)
public class DateListFragment extends ListFragment {
private int mposition = 1;
private String[] mListItem = new String[] {
"Lundi 9 Juilllet",
"Mardi 10 Juillet",
"Mercredi maintenant"
};
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
this.setListAdapter(new ArrayAdapter<String>
(this.getActivity(),R.layout.frag_list_view ,mListItem));
this.getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
}
and here is fiche_frag :
public class fiche_frag extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
return inflater.inflate(R.layout.checks_matin,container,false);
}
R.layout.checks_matin works fine alone.
I thank you already and again for your help. I'm a beginner in android environnement and I find it difficult to englobe every notions for the UI at once... !!
You understand the basics. The FrameLayout goes wherever you want your fragment(s) to go. I've done it where my whole screen was one single FrameLayout before and I swapped up to five different fragments in and out of it.
If you have two Fragments that you want to display simultaneously, you could make your main layout with two FrameLayouts. However, this means you are locked into having both there all the time (or an empty space if you remove one.
If you want two fragments that don't have to be on the screen at the same time you use a single FrameLayout and write code to swap the fragments as required.
Code to instantiate fragments should always be in the controlling activity (if they are dynamic).
Without code and a more specific problem, the above is the best answer I can give you.
EDIT
An example main layout to put two fragments side by side:
<?xml version="1.0" encoding="utf-8"?>
...
<LinearLayout
android:id="#+id/frames"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#id/hline1"
android:layout_below="#id/horizontalline"
android:orientation="horizontal" >
<FrameLayout
android:id="#+id/leftpane"
android:layout_width="0px"
android:layout_height="match_parent"
android:layout_weight=".4" />
<FrameLayout
android:id="#+id/rightpane"
android:layout_width="0px"
android:layout_height="match_parent"
android:layout_weight="1" >
</FrameLayout>
</LinearLayout>
...
To add your fragment to one of the framelayouts:
FragmentClass fragment = new FragmentClass();
getFragmentManager().beginTransaction().add(R.id.leftpane, fragment).commit();
If you want to swap fragments in one of the framelayouts (say the left pane), you can do it like this:
FragmentClass fragment = new FragmentClass();
getFragmentManager().beginTransaction().replace(R.id.leftpane, fragment).commit();
I suggested instantiating from the XML because it sounded like you were going to have two fragments and not make any changes. If you are going to swap them in and out, then it would be appropriate to add a tag to each one so you can find them again if you want to display them again.

Categories

Resources