I'm writing a very simple android app. When the user touches the surface and moves their finger around, pictures are drawn below their fingers. When their finger is raised, this stops.
I want the action bar to hide when the finger is down and reappear when it is raised.
The ActionBar is overlayed. I thought using ActionBar.hide() and .show() in my view's onTouchEvent would work fine, but I've hit some problems.
I've tried a few things. First I tried passing the ActionBar created in the Activity into the view, but this didn't work as the view has to be created before the ActionBar is "got", so I would just be passing in a null value.
I then tried to make a static ActionBar which I can call from my view, but then I get this error: "Only the original thread that created a view hierarchy can touch its views.”
Anyone know of a way around this?
Take a look at one of the examples that is part of the jfeinstein10's Sliding Menu library
In it, in the BirdActivity.java, you will see how the ActionBar is shown and hidden after 2 seconds. You will naturally have to adapt the code yourself. But this should get you started:
Excerpt of the code from Line No. 53 - 58:
imageView.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
getSupportActionBar().show();
hideActionBarDelayed(mHandler);
}
});
The hideActionBarDelayed() from Line No. 80 - 86:
private void hideActionBarDelayed(Handler handler) {
handler.postDelayed(new Runnable() {
public void run() {
getSupportActionBar().hide();
}
}, 2000);
}
UPDATE
For the lack of code, most of the problem has been assumed. It may be wrong simply for the lack of data from the OP. That being said, if sorting out the "Only the original thread that created a view hierarchy can touch its views." problem will fix it, perhaps this may do it for you:
Runnable run = new Runnable() {
#Override
public void run() {
// RUN YOUR CODE TO HIDE / SHOW THE ACTIONBAR HERE
}
}; YOUR_ACTIVITY.this.runOnUiThread(run); // REPLACE WITH getActivity().runOnUiThread(run); IF THIS IS A FRAGMENT
NOTE: In the example, the activity in question uses ActionBarSherlock and extends SherlockActivity and therefore, the use of getSupportActionBar(). If you are not using ABS, you will have to use getActionBar() instead of the former.
Related
OK,i have ScrollView with multiply recyclerview-s.When user click on some item on my list that item expand itself with some more info. The problem is that although it does expand correctly, my root view(in my case ScrollView) does not follow that expansion automatically ,so i need to scroll manually to see expanded item.So i used scrollView.fullScroll(View.FOCUS_DOWN) in onClick in my recyclerview.And it works fine but after this line of code is triggered every other click on some other recycelerView it scroll down although that recyclerview does not have fullScroll().
I tried to use scrollTo(),smoothScrollTo etc.I dont use ExpandableRecyclerView but cachapa/ExpandableLayout and in this thread developer said that it is rather the parent View "issue".Also tried solution from the same thread but problem persist.
So my question is how to stop triggering fullScroll(View.FOCUS_DOWN) when i click on other recuclerviews items.
my code:
` animaton.setOnClickListener(v -> {
notifyDataSetChanged();
//some stuff
scrollView.post(new Runnable() {
public void run() {
scrollView.fullScroll(View.FOCUS_DOWN);
}
});
});`
I am very new to Java. I am doing a school project at the moment and I have my main activity, then I have a settings activity. I am trying to modify the xml from the main activity with the settings activity. I am able to modify the settings xml file with the settings.java, but I would like to modify the main activity xml with settings.java
public class Settings extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
// Get the Intent that started this activity and extract the string
Switch switchButton;
final RelativeLayout mRelativeLayout = (RelativeLayout) findViewById(R.id.activity_settings);
final RelativeLayout mRelativeLayoutMain = (RelativeLayout) findViewById(R.id.activity_main);
switchButton = (Switch) findViewById(R.id.switch1);
switchButton.setChecked(true);
switchButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean bChecked) {
if (bChecked) {
mRelativeLayoutMain.setBackgroundColor(Color.GRAY);
mRelativeLayout.setBackgroundColor(Color.GRAY);
} else {
mRelativeLayoutMain.setBackgroundColor(Color.WHITE);
mRelativeLayout.setBackgroundColor(Color.WHITE);
}
}
});
if (switchButton.isChecked()) {
mRelativeLayoutMain.setBackgroundColor(Color.GRAY);
mRelativeLayout.setBackgroundColor(Color.GRAY);
} else {
mRelativeLayoutMain.setBackgroundColor(Color.WHITE);
mRelativeLayout.setBackgroundColor(Color.WHITE);
}}
public void toast1(View view) {
android.widget.Toast.makeText(this, "Created by Cody Walls and Tommy Serfas", android.widget.Toast.LENGTH_LONG).show();
}
/*public void switch1(View view) {
ScrollView mScrollView = (ScrollView) findViewById(R.id.scrollView);
mScrollView.setBackgroundColor(Color.GRAY);
}*/
}
In the Code I am trying to change the background of the main activity xml with :
mRelativeLayoutMain.setBackgroundColor(Color.GRAY);
and when I run the app and click the intent it will crash with the error:
"java.lang.NullPointerException: Attempt to invoke virtual method
'void android.widget.RelativeLayout.setBackgroundColor(int)' on a null
object reference"
I think the easiest way is to create an PreferenceManager.SharedPreferences, in which I recommend you to store current app data. This will help you not to loose any changes in app after you exit the it. Here is short instructions:
Create button in settings activity which will change something in main activity.
Create onClickListener for your button.
Use .SharedPreferences to store was you button clicked or not. (I recommend storing boolean variables, this way you can store was button clicked or not.)
I both of your activities in onCreate method call .getSharedPreferences to read saved app values. (I mean to read was the button clicked or not.)
Use app values you got from 4. to change any element in activity. (For example if you stored that button was clicked, then change some TextView text or etc.)
I hope you understood the idea.
Link to the Android developer tutorial about App key values storing & saving
Link to the StackOverflow much easier explanation & examples
There are a couple of ways of doing this (Some of which depends on how you are switching back and forth from each activity). It also depends on what things you are changing.
From your settings page, as you are changing different settings, you'll save this content within Preferences. (You can see more how to use Preferences here: https://examples.javacodegeeks.com/android/core/ui/settings/android-settings-example/ or by just Googling it).
On you main activity, depending on how you come back to it (onStart most likely), you can setup the things you need to programmatically.
So, you may need to do a little research on the Android lifecycle and how each cycle works (https://developer.android.com/guide/components/activities/activity-lifecycle.html), how to program the UI programmatically through Java (http://startandroid.ru/en/lessons/220-lesson-16-creating-layout-programmatically-layoutparams.html), and the Preferences Android library to save certain settings.
The xml isn't meant to be "altered". You can change the UI programmatically. It's possible to build an Android app without any xml. When Android was first built, it didn't use the xml to create the UI. It was all done through Java. It was then added to use xml to create your activities or fragments or any UI component. This made things easier for more static activities or activities with very little dynamic content.
I want to launch an activity, and show the progress of the loading of the activity as methods are completed. The methods will, for example, be downloading data. The problem is, the loading bar never actually shows as empty at the beginning, it simply loads once all methods are complete and shows 100% full.
I have tested a few implementations, but with no luck. The current state I am in is that I set the loading bar to max in onCreate, then carry out processing in onWindowFocusChanged. The issue is, that the loading bar is never drawn after onCreate. I have tested placing methods into onResume also, but again the progress bar only appears AFTER onCreate, onResume and onWindowFocusChanged have all completed. This has thrown my understanding of the activity lifecycle off a bit as I thought all visual elements should be drawn after onCreate?
My current code is as follows (note that no difference is noticed if the code in onWindowFocusChanged is placed in onResume). This code is all prototyping code in an attempt to get this to work.
public class IntermediateLoadingScreen extends AppCompatActivity {
private ProgressBar loadingBar = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_intermediate_loading_screen);
loadingBar = (ProgressBar)findViewById(R.id.intermediateLoadingBar);
loadingBar.setMax(100);
Log.d("IntermediateLoadScreen","onCreate Complete");
}
#Override
public void onResume () {
super.onResume();
Log.d("IntermediateLoadScreen","onResume");
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
Log.d("IntermediateLoadScreen","onWindowFocusChanged");
if(hasFocus){
AsyncCollectDeviceData asyncCollectDeviceData = new AsyncCollectDeviceData(this.getApplicationContext());
asyncCollectDeviceData.execute();
loadingBar.setProgress(15);
Log.d("IntermediateLoadScreen", "Loading");
getUserContactsFromServer();
getUserGroupsFromServer();
loadingBar.setProgress(100);
/*Intent intent = new Intent(this, nextActivity.class);
startActivity(intent);*/
}
}
public void getUserContactsFromServer(){
Log.d("IntermediateLoadScreen", "getUserContactsFromServer");
loadingBar.setProgress(35);
ContactsResponse contactsResponse = new ServerRequest().submitContactsRequest();
new UserRealmDAO().updateContacts(contactsResponse);
loadingBar.setProgress(60);
}
public void getUserGroupsFromServer(){
Log.d("IntermediateLoadScreen", "getUserGroupsFromServer");
loadingBar.setProgress(80);
GroupsResponse groupsResponse = new ServerRequest().submitGroupsRequest();
new UserRealmDAO().updateGroups(groupsResponse);
loadingBar.setProgress(95);
}
}
I understand that I shouldn't really have a loading screen in an activity of it's own, and should probably have it as part of an activity that I can make visible when required. But the same activity flow should occur, so if I can get this example working it should transfer across.
To conclude, the loading bar does not show after onCreate, the previous activity simply hangs and a complete loading bar eventually pops up. How can I have the empty loading bar drawn at the beginning and fill it as i call 'loadingBar.setProgress'?
EDIT:
These are my logs I have added to the above activity, I have moved the code shown in onWindowFocusChanged into onResume:
01-20 13:10:15.430 /IntermediateLoadScreen: onCreate Complete
01-20 13:10:15.430 /IntermediateLoadScreen: onResume
01-20 13:10:20.425 /IntermediateLoadScreen: Bar set at progress 15
01-20 13:10:26.242 /IntermediateLoadScreen: Bar set at progress 80
01-20 13:10:31.457 /IntermediateLoadScreen: Bar set at progress 100
The first (splashscreen) activity stays displayed until all these logs have printed out. I have placed a Thread.sleep before every progress bar set call, so you can see that there is a at least 5 seconds between each log. Even after doing this, my activity does not display until ALL method calls in the entire class are complete.
Problem is onWindowFocusChanged(boolean hasFocus) will be called right after activity is created. So your progress bar will have 15% at beginning.
Also all your methods may run really fast, so they will be done before user can actually see some progress
Just a suggestion here. Generally if any data is to be loaded/background process to take place, there is a new feature in Android Lollipop called SplASHsCREEN. Try using THIS Splash screen- a basic app screen where it will be shown till you load all your data and after it loads, you can show the next screen.
This gives user a good feel just after launching the app instead of displaying progress bar.
I am trying to display Loading text only when its loading.
The problem is im setting it to visible and straight after to invisible once finished loading. But text never has a chance to update. Is there a way to force refresh the screen, or maybe there is another way to do this?
Thanks
This is my code
SearchBtn = (Button) findViewById(R.id.SearchButton);
SearchBtn.setOnClickListener(new OnClickListener()
{
public void onClick(View arg0)
{
//this is never seen because its set straight after to invisible
LoadingText.setVisibility(View.VISIBLE);
SearchFor(EditSearchField.getText().toString()); // all loading done here
LoadingText.setVisibility(View.INVISIBLE);
HideKeyboard();
}
});
You need to do the actual load in a separate thread. You'd be best off using an AsyncTask for this. Take a look at http://www.vogella.com/articles/AndroidPerformance/article.html
I wanted to move some linear layout using TranslateAnimation. I have 2 problems. My base SDK is Android 2.2.
Even when the animation is finished, the touchable area in the linear layout was not moved at all.
The screen flashed for a couple of frames right after the animation was finished.
At first, I didn't use AnimationListener and LinearLayout.layout(). When I fnished the animation using the following code, the position of the view was indeed changed. But it seemed that the touchable area was not moved with the view during animation. As a result, when I tried to clicked any of the buttons on the view after animation, nothing happened. If I clicked the original area of the buttons (the original area before the animation took place), the on_click_listener was triggerred.
Then i deleted this line of code,
tmpAnimation.setFillAfter(true);
and tried AnimationListener and LinearLayout.layout(). It did help and sovled the 1st problem.
But there came the 2 problem. After the animation, some of my linear layouts would flash for a couple of frames and then back to order.
I've tried midLinearlayout.requestLayout(), it doesn't work.I tried implemented Animation.AnimationListener and override onAnimationEnd like someone said,but it doesn't work either.
TranslateAnimation tmpAnimation = new TranslateAnimation(midLinearlayout.getLeft(),midLinearlayout.getLeft(),midLinearlayout.getTop(),midLinearlayout.getTop()+100);
//tmpAnimation.setFillAfter(true);
tmpAnimation.setDuration(2000);
tmpAnimation.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
//To change body of implemented methods use File | Settings | File Templates.
}
#Override
public void onAnimationEnd(Animation animation) {
Log.v("onflingTest","top="+midLinearlayout.getTop()+" left="+midLinearlayout.getLeft()+" right" + midLinearlayout.getRight());
midLinearlayout.layout(midLinearlayout.getLeft(), midLinearlayout.getTop()+100, midLinearlayout.getLeft() + midLinearlayout.getMeasuredWidth(), midLinearlayout.getTop()+ 100 + midLinearlayout.getMeasuredHeight());
}
#Override
public void onAnimationRepeat(Animation animation) {
//To change body of implemented methods use File | Settings | File Templates.
}
});
I've solve this by the code below:
linearlayout.clearAnimation();
see the link:
EditText stucks after animation and alive back on scrolling......?
I solved the issue with the help from post View.GONE in animation complete
The problem is after layout B completes the animation, i missed to make the view state as View.GONE. Adding View.GONE brought back the controls.