How to show another content over ViewPager? - android

I have the following problem:
I have MainActivity, where ViewPager is placed. Page of ViewPager is Fragment, which contains imageview and several textviews. When user clicks on the image, another content should be shown. And probably I don't understand how can I do it. As I know, I can't place FrameLayout on my Page Fragment and here show another fragment with needable content. Also I cannot place this fragment on MainActivity, as I cannot change it from my fragment (and if I want to change ViewPager on my Fragment with needable content, I cannot catch clicks on ImageView). I found one solution: to have 2 layouts on Page Fragment (first for ViewPager and second for content, which will be shown after), and change their visibility each time, but I don't think that this is the best idea. So, maybe you have better variants?
UPD
I need form this
after clicking on image get this:

you can use VeiwSwitcher wich you can learn about it here
public class ViewSwitcher extends ViewAnimator that switches between two views, and has a factory from which these views are created. You can either use the factory to create the views, or add them yourself. A ViewSwitcher can only have two child views, of which only one is shown at a time.
for example :
<ViewSwitcher
android:id="#+id/viewSwitcher1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:inAnimation="#android:anim/slide_in_left" >
<LinearLayout
android:id="#+id/view1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
//Content of first layout
</LinearLayout>
<LinearLayout
android:id="#+id/view2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
//Content of second layout
</LinearLayout>
</ViewSwitcher>
so basically you have Two ViewGroup and first one is visible to user and second one is hidden . and you can only have Two View in side of ViewSwitcher and you can switch between them with a Button :
viewSwitcher = (ViewSwitcher)findViewById(R.id.viewSwitcher1);
myFirstView= findViewById(R.id.view1);
mySecondView = findViewById(R.id.view2);
button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
if (viewSwitcher.getCurrentView() != myFirstView){
viewSwitcher.showPrevious();
} else if (viewSwitcher.getCurrentView() != mySecondView){
viewSwitcher.showNext();
}
}
});
and it dos not matter what kind of view or id used for those Two views.
so just put ViewSwitcher in your Fragment layout and put your image through xml or programmatically . and use Two Button one in the first layout and one in the second layout to switch between them. hope this works for you. you can also use Dialog but in your case it will make it ugly!

Related

How to replace parent fragment view with a child fragment's view?

I'm looking for some help in Android studio with replacing a parent fragment's view with the view of a child fragment when a view in the parent fragment is clicked. Thank you in advance for your help.
Right now I have a parent fragment which is a chat list, and a child fragment (the chat screen) that shows up when you click on an element of the chat screen (i.e. a button). The chat list looks like this:
<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="com.example.myapplication.ChatListFragment">
<!-- Empty Container for Fragment to Live in -->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ListView
android:id="#+id/chatListView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/moonstone">
</ListView>
</FrameLayout>
I have set the onClickListener for the chatListView as follows:
_chatListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String chatName = _chatListAdapter.getItem(i).getChatTitle();
openChatScreen(chatName);
}
});
And the openChatScreenWindow() looks like this:
private void openChatScreen(String chatName)
{
_fragmentManager = getChildFragmentManager();
Log.i(CHAT_LIST_TAG, "starting chat screen fragment");
FragmentTransaction fragmentTransaction = _fragmentManager.beginTransaction();
ChatScreenFragment chatScreenFragment = ChatScreenFragment.newInstance(chatName);
fragmentTransaction.add(R.id.fragment_container, chatScreenFragment);
fragmentTransaction.addToBackStack(GlobalConstants.OPEN_CHAT_WINDOW_FRAGMENT_STRING + chatName);
fragmentTransaction.commit();
}
However, when I run this code, the child fragment is obscured, because both the frame layout (the view that the fragment is displayed in) and the chatListView have their widths and heights set to match_parent (I figured this out by testing the height and width of the chat list as 200dp, and I was able to see the child fragment behind it).
Is there a simple way to get the fragment to replace the chatListView whenever it is loaded?
For example, is there a way to change this view:
To this one:
... when an element in the chat list (the first one) is clicked?
I was thinking of changing the list view's visibility to invisible and visible based on whether the fragment is loaded, but that seems like a headache.
Please let me know what you think, thank you!
First off most modern way of managing fragments is - Navigation component
According your approach - you are adding child fragment on top of the prev fragment with fragmentTransaction.add, you can use fragmentTransaction.replace instead
Also, you might want to set child fragment background to solid color - to hide previous fragment, if you use this method - make child's fragment root clickable - to prevent fragments click through.
My recommendation - spend more time on learning Navigation component

Android - Fragment with two buttons

I am working on building an Android application that has a fragment with two buttons, either "News" or "Social". It gets initialised with news, and then if "Social" button is clicked during runtime, it should refresh the fragment with the social's relevant content. Is there a way to do that?
One way to do it is putting two views on the fragment and show/hide properly:
<!-- News -->
<FrameLayout
android:id="#+id/news_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- News content -->
</FrameLayout>
<!-- Social -->
<FrameLayout
android:id="#+id/social_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Social content -->
</FrameLayout>
Then, on Java, you use these containers:
// show news and hide social example
socialContainer.setVisibility(View.GONE)
newsContainer.setVisibility(View.VISIBLE)
Yes you can do it by setting to values of ui elements in on click listener of buttons and pass the respective content of the clicked button. But in case you want to represent information differently then you need to make container layouts and set visibility according to the button clicked.
In your news tab you can achieve the same by following code
newsBtn.setOncliclListener(this);
socialBtn.setOncliclListener(this);
and in your onclick method write down the code for updating your view according to btn click
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.newsbtn:
socailview.setVisibility(View.GONE);
newsview.setVisibilty(View.VISIBLE);
loadYourNewsViewData();
break;
case R.id.socialbtn:
newsview.setVisibilty(View.GONE);
socailview.setVisibility(View.VISIBLE);
loadYourSocialViewData();
break;
}
}
you can use this code in your main activity to load news fragment as first fragment
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="name of your news fragment class"
android:id="#+id/newsFragment"/>
Personally, I would:
Make a container Fragment (just those two buttons of yours), which contains a FrameLayout.
Make a base abstract class of BaseNewsFragment, which is going to be a parent for your NewsFragment and SocialFragment.
Dependent of which button was clicked, I would call a method to replace a content of the FrameLayout with an argument of specific fragment

View.layout() works until next UI update

My launching activity consists of Linear layout with two buttons. Both buttons have listeners: the first one (b) moves itself upon click: 30px to the left and 30px back upon the next click.
The second one (b2) changes its text upon click. Here is the code:
public class TestActivity extends Activity {
public final String TAG="TestActivity";
boolean toTop=true;
boolean setInitialText=false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button b=(Button)findViewById(R.id.button);
Button b2=(Button)findViewById(R.id.button2);
b.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
int modifier;
if(toTop) modifier=-30;
else modifier=30;
v.layout(v.getLeft()+modifier,v.getTop(),v.getRight()+modifier,v.getBottom());
toTop=!toTop;
}
});
b2.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
String currentText;
if(setInitialText)currentText="Press to change text";
else currentText="Press to change back";
((Button)v).setText(currentText);
setInitialText=!setInitialText;
}
});
}
}
XML layout-file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical" >
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Press to begin animation" />
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Press to change text" />
My problem: when b is moved to the left and I press b2, b moves to its initial position. Why? I don't want it to move back and didn't specify it anywhere.
It looks like View.layout looses its effect. Why it happens? I tested that in other situations and it seems that any UI update makes all invoked View.layout methods loose their effect.
In my main project there is a ListView which is populated with images from background - all view moves loose effect when new image appears. Besides, if I add EditText and try to enter something (as user), view moves loose their effect as well. Can anyone explain to me what's going on and why do views move back?
Looks like parent layout repositions it's siblings after you set a new text for the button2, because as describe in xml, button2 wraps it's content by width and height.
As you changed button's content, it requests it's parent layout to get a new position for it. In this case parent layout will recalculate position values for all of it's siblings. That's why button1 also comes back to it's previous position.
Keep in mind, that you also set the gravity value for parent layout as center, that means that when layout will position it's siblings it will position them in it's center.
Try to experiment with some ohter layout classes like FrameLayout, which has absolute manner of positioning it's siblings and RelativeLayout which and also try your case getting rid of layout's gravity.
Here says that this issue may be solved, using view.setLayoutParams() instead of view.layout()

How to implement a "click-anywhere-to-continue" event on my android activity?

Is this possible?
I would display an activity that shows a welcome page, and that welcome page doesn't have any Views where I can attach an onClickListener.
EDIT: ok, the reason for this welcome kind of welcome page, is that this application is used to take something like a survey... after a customer is done with the survey, the app returns to this welcome page so another person can take the survey again.
Yes, if the original layout is somehow not appropriate, use a FrameLayout at the top level of your layout to achieve this. FrameLayout allows stackable views/layouts, so you can have your existing view as the bottom layer, and then a transparent view on top that listens for the touch event:
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<!-- Put your complete original layout/view here -->
<View
android:id="#+id/view_to_listen_for_touch"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</FrameLayout>
try like this,
welcome screen xml layout.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mainLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</RelativeLayout>
add this in your activity,
private RelativeLayout mainLayout;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.welcome_screen);
mainLayout=(RelativeLayout)findViewById(R.id.mainLayout);
mainLayout.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// here you can write code to proceed next step.
}
});
}
I think you are using an XML layout for this page. And using at least one ViewGroup (e.g Linear Layout/Relative Layout etc). Put an id to this ViewGroup element and In the Activity initialize this ViewGroup element using find view by id. Now set the click listener to the ViewGroup element

LinearLayout (with onClick) containing ImageButton - is there a better way to solve it?

At the moment I have something like that:
<LinearLayout android:layout_height="80dip" android:id="#+id/linearLayoutSettings"
android:layout_width="80dip" android:orientation="vertical">
<ImageButton android:layout_height="wrap_content" android:src="#android:drawable/ic_menu_manage"
android:id="#+id/imageButton1" android:layout_width="wrap_content"></ImageButton>
</LinearLayout>
LinearLayout has onClick listener attached to it.
Problem: When a ImageButton is clicked inside the LinearLayout, the event doesn't get triggered.
I could solve it by attaching the same on click to this button as I attached to LinearLayout. But in that case it would mean a lot of repetetive code (have many buttons).
Question: Is there a more effective way to solve this problem?
Change the ImageButton to an ImageView and you will start getting the click event
Attach the following tag to each imagebutton:
android:onClick="yourOnClickFunction"
Then, in your activity, add a corresponding function:
public void yourOnClickFunction(final View v) {
switch(v.getId()) {
//Do whatever is necessary.
}
}
In the switch-block you need to know about the buttons IDs. You can get them via findViewById(R.id.aButton).
You can write loop finding all buttons in layout and attach once created listener to all of them.
If I understand correctly, when the button is clicked, the LinearLayout's onClickListener doesn't fire. Which makes sense.
What you can do is put a yourLinearLayout.performClick(); which will programatically fire the layouts onClick event. If you put it at the end of the buttons onClick then it will perform the buttons, then the layouts, in order.
you must set the attribute setClickable(true);!!
you can access it in xml using android:clickable="true"

Categories

Resources