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.
Related
Anyone know how i can move an imageview to another imageview ?
im thinking at this kind of method, or maybe is another one that i dont know... no problem, im glad to learn it
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true"
android:interpolator="#android:anim/linear_interpolator">
<translate
android:duration="800"
android:fromXDelta="0%p"
android:toXDelta="75%p" />
i know that fromXDelta (is the starting position) and the toXDelta is the possition where should arrive.. but? how i can know what is my starting position and arrive position looking at my picture example?
Added details:
There are 4 different layouts in here, but only 3 are with weight value.
The bar from top where are buttons is a layout but not have weight like the rest.
So laying cards from up are in the layout1
My desired position to arrive are in the layout2
Playing cards from down are in the layout3
Also i use onClick methods in xml not onClickListeners. Thanks
You can do this programmatically like this :
#Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final View target = findViewById(R.id.target);
final View viewToMove = findViewById(R.id.viewToMove);
viewToMove.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View v) {
translate(viewToMove, target);
}
});
}
private void translate(View viewToMove, View target) {
viewToMove.animate()
.x(target.getX())
.y(target.getY())
.setDuration(1000)
.start();
}
Here the XML :
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
android:id="#+id/activity_main"
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">
<ImageView
android:id="#+id/target"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:background="#color/colorAccent"/>
<ImageView
android:id="#+id/viewToMove"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#color/colorPrimary"
android:src="#mipmap/ic_launcher"/>
</FrameLayout>
Finnaly i have succeded with the help of user Francois L.
Was a lot of work to do, i don't say no, because i needed to redesign all my layouts, but this is no problem cause i learned something new and i appreciate all the help i can receive.
If anyone want to move a view (any type of view, imageview, buttonview, textview etc ) to another view it is necessary that both views to be in the same layout, that is the most important part.
And the code to achieve this is:
//here is the part of initialization
ImageView poz1Inamic = (ImageView) findViewById(inamic_pozitia1);
ImageView poz1InamicSpateCarte = (ImageView) findViewById(inamic_pozitia1spatecarte);
//other code
poz1InamicSpateCarte.setVisibility(View.INVISIBLE);
//here is the initialization of the arrive position
ImageView cartePusaInamic = (ImageView) findViewById(R.id.cartePusaInamic);
//the code for moving from start position to arrive position
poz1Inamic.animate()
.x(cartePusaInamic.getX())
.y(cartePusaInamic.getY())
.setDuration(333)
.start();
I'm looking for a solution to this that will allow me to expand a cardview to see more information and then easily collapse it. Google Keep has examples of cards like this. Anyone know how they do this? Would I create 2 versions of my cardview (one collapsed and one expanded) and then use an Animator class coupled with gesture methods to transition between the two views? I'm using a Recyclerview to hold my cardviews.
I found this if it is at all relevant: http://developer.android.com/training/animation/layout.html
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:orientation="vertical"
android:animateLayoutChanges="true"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
//here put the view which is always visible
<LinearLayout
android:layout_width="match_parent"
android:visibilty="gone"
android:id="#+id/expandableLayout"
android:layout_height="wrap_content">
//here put which will collapse and expand
</LinearLayout>
</android.support.v7.widget.CardView>
take a boolean isexpanded in you arraylist object class
if (listobj.isexpanded)
{
holder.expandableLayout.setVisibility(View.VISIBLE);
}
else {
holder.expandableLayout.setVisibility(View.GONE);
}
holder.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (listobj.isexpanded)
{
holder.expandableLayout.setVisibility(View.GONE);
listobj.isexpanded=false;
notifyItemChanged(position);
}
else {
holder.expandableLayout.setVisibility(View.VISIBLE);
listobj.isexpanded=true;
notifyItemChanged(position);
}
}
});
try someting like this
I'm using the setOnTouchlistner class for detecting left and right swipes. I can get it to work fine on a listview, but the listview is too small to get a good swipe every time.
I then tried to set the swipe to the main LinearLayout. I have three other LinearLayout inside this. But it is not working thanks for any help.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:baselineAligned="false"
android:orientation="horizontal"
android:id="#+id/driveView"
android:focusableInTouchMode="true"
android:focusable="true"
android:clickable="true">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical" >
Here is the code:
private LinearLayout myView = null;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.drive);
myView = (LinearLayout)findViewById(R.id.driveView);
myView.setOnTouchListener(new OnSwipeTouchListener(mContext) {
#Override
public void onSwipeLeft() {
showdrivedialog(mContext, "Drive List", "Change to Ascending list!");
}
public void onSwipeRight() {
showdrivedialog(mContext, "Drive List", "Change to Descending list!");
}
});
Two matters I want to mention.
1) I don't know about OnSwipeTouchListener but I got interested. I suspect android:clickable="true" should be false because there seems to be a conflict between swiping and clicking.
2) Look at this SO link # How to handle right to left swipe gestures. I don't know where you got the OnSwipeTouchListener class but you can copy the one with 274 votes!
Personally I did not use this class. I have used and extended HorizontalScrollView.
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);
}
});
// ...
}
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.