Adding Background images in ADT - eclipse

I really need help (am a newbie to ADT/Eclipse), I set up a back ground image by placing the image first in the res/drawable folder and then proceeded to place it in my application usind the:
android:background = "#drawable/image"
I then proceeded to change the layout to "scrollview"
The image appeared in the Graphical layout but after a while, ADT showed me an error saying:
(Where the error is at where "R" is written e.g. setContentView(R.layout.activity_main);
the error reads "R cannot be resolved to a variable"
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
I would kindly appreciate if anyone helps :D

Related

Fragment inside ViewPager disappears on swiping

The Context
I have a HomeActivity that contains a NewsFragment. The NewsFragment contains a ListView to display news items in a list. I have a ViewPager that is added as a header-view to the ListView. This ViewPager appears as a header to the list and contains a DateFragment to display the date. The first time the user opens the HomeActivity, I want "TODAY" to be the date. When the user swipes the DateFragment to the left, I want the date text to show "TOMORROW". Swipe again and it should show the day after tomorrow. Similarly, when the user swipes in the other direction, I want to display "YESTERDAY", the day before yesterday etc. The ViewPager should support swiping infinitely (or a very large number) in both directions.
Here's how they are nested - http://tinypic.com/r/31623qw/8. (I don't have the reputation to post images yet, but this diagram is super useful for understanding this question).
The Problem
For simplicity, I'm displaying the index of the fragment as the date. When I first open the app, I see "Date: 0" being displayed as the date in the DateFragment. When I swipe the fragment to the left (to go to the next day), I can see the next fragment appear with "Date: 1" being displayed, but almost immediately, the fragment disappears. Once the fragment disappears, nothing reappears, and I just see an empty container. I can swipe to bring back the "Date: 0" Fragment, but I can't see any other Fragments. (I'm using the - Infinite View Pager by Antony T. - https://github.com/antonyt/InfiniteViewPager)
The Gory Details
I have a HomeActivity that contains a NewsFragment. The NewsFragment contains a ListView to display news items as a list. Here is the layout.xml for the NewsFragment:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
I have a ViewPager that is dynamically added as a header to this list. So inside NewsFragment, I first initialize the ListView:
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.home_news_fragment, container, false);
list = (ListView) view.findViewById(android.R.id.list);
emptyView = view.findViewById(android.R.id.empty);
list.setEmptyView(emptyView);
return view;
}
Next, in onActivityCreated(), I initialize and load the header for the ListView, and then load the news feed items:
#Override
public void onActivityCreated(final Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
loadHeader();
loadNewsFeed();
}
In the loadHeader() method, I then dynamically create a LinearLayout container to contain my ViewPager. I create a PagerAdapter for the ViewPager and I wrap it with an InfiniteViewPager to allow infinite swiping in both directions. I then create a ViewPager and I add it to the LinearLayout container. I then add the container as a Header View to the ListView:
private void loadHeader()
{
final LinearLayout headerContainer = new LinearLayout(getActivity());
headerContainer.setId(R.id.header_container_id);
headerContainer.setLayoutParams(new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
headerContainer.setOrientation(LinearLayout.VERTICAL);
// initialize the pager adapter for the view pager
PagerAdapter pagerAdapter = new HeaderPagerAdapter(getActivity().getSupportFragmentManager());
// Create a view pager. I use a custom implementation of a view pager I found from another Stackoverflow answer - WrapContentHeightViewPager - that allows ViewPager's layout.height to wrap content. The original ViewPager does not allow wrapping of content.
WrapContentHeightViewPager mViewPager = new WrapContentHeightViewPager(getActivity());
mViewPager.setId(R.id.view_pager_header);
mViewPager.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT));
// wrap pager to provide infinite paging with wrap-around
PagerAdapter wrappedAdapter = new InfinitePagerAdapter(pagerAdapter);
mViewPager.setAdapter(wrappedAdapter);
// Add the view pager to the header container
headerContainer.addView(mViewPager);
// add the container as a header view to the list
list.addHeaderView(headerContainer);
}
In the loadNewsFeed() method, I do an async fetch of the news feed items and populate the list by adding the items into the footer view. I won't go into the implementation details for this - outside the scope of this question.
The NewsFragment contains my pager adapter, which contains the getItem method that initializes the Fragment to be displayed by the ViewPager:
private class HeaderPagerAdapter extends FragmentPagerAdapter
{
public HeaderPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
return DateFragment.newInstance(i);
}
#Override
public int getCount() {
return Integer.MAX_VALUE;
}
}
And here is the actual Fragment to be displayed inside the ViewPager:
public class DateFragment extends Fragment
{
private int index;
TextView date;
public static final DateFragment newInstance(int index) {
DateFragment fragment = new DateFragment();
final Bundle args = new Bundle(1);
args.putInt(Constants.Extras.PAGE_INDEX, index);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
index = getArguments() != null ? getArguments().getInt(Constants.Extras.PAGE_INDEX) : 1;
}
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState)
{
View v = (ViewGroup) inflater.inflate(R.layout.summary_fragment, container, false);
date = (TextView) v.findViewById(R.id.tvDate);
return v;
}
#Override
public void onActivityCreated(final Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
date.setText("Date: " + index);
}
}
For now I am simply using the index to be displayed as the date. I want to replace this with the actual date. Why does the fragment disappear on swipe?
Considerations:
Is there a refresh/redraw event that gets called?
Does it have to do with extending FragmentPagerAdapter vs. FragmentStatePagerAdapter
Override destroyItem() or instantiateItem()?
Set up a onPageScrolled listener on the ViewPager and then handle the page scroll events? I tried thehayro.blogspot.com/2012/12/enable-infinite-paging-with-android.html and that causes my fragments to disappear and then appear after a while.
Is it because I am adding the ViewPager as a header to the list view? The list view scrolls up and down and the view pager left and right. I've added this to my ViewPager implementation to tell the list view to stop intercepting our touch events:
#Override
public boolean onInterceptTouchEvent(MotionEvent ev)
{
// Tell our parent to stop intercepting our events!
boolean ret = super.onInterceptTouchEvent(ev);
if (ret)
{
getParent().requestDisallowInterceptTouchEvent(true);
}
return ret;
}
I'm sorry about the length of this post. I felt this much detail might be necessary. Thoughts?

Update Activity's UI when it is not visible [Another activity is in foreground]

Is it ok to update an Activity when it is not in the foreground. I am not asking if it can be done from a background thread.
Consider this:
I have two activities Activity-A and Activity-B.
I start an AsyncTask from Activity-A and then go to Activity-B. Now after sometime, the AsyncTask finishes and in the onPostExecute() method, I try to update the images that are in Activity-A. All this is happening when Activity-B is in the foreground.
Is the above scenario reasonable or do I have to wait till Activity-A is in the foreground to update its UI?
If I can safely update the UI in the above scenario, what should I do when Activity-A is killed or finished and the AsyncTask still completes and tries to update the UI? [Assuming I have to do a check for isFinishing before updating the UI]
The above is a simplified version of what I am trying to do. I actually have a Custom ImageView that loads images from the server and updates itself when the request is done. So I am wondering what scenarios I have to worry about if the view is updating itself when the activity is not in foreground or has finished/destroyed.
EDIT:
Here is a sample that is working.
public class MainActivity extends Activity implements OnClickListener {
ImageView mImageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImageView = (ImageView) findViewById(R.id.iv_image);
findViewById(R.id.btn_activity_2).setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_activity_2:
new BackGroundTask().execute();
startActivity(new Intent(MainActivity.this, Activity2.class));
break;
}
}
private class BackGroundTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
mImageView.setImageResource(R.drawable.ic_launcher);
}
}
}
The Layout is just a LinearLayout with button and image.
No, it's not. You can't update a UI that's not visible :) Activity A is onPause (or Stopped if needed).
You have to implement a reasonable Activity LIfeCycle so ActivityA can update its UI during onResume(); The AsyncTask should only touch the data that the UI needs to draw itself.
Your "Custom IMage View" has to be able to load the image from a place outside the Activity.
If your CustomImageView is (or can pass as a regular ImageView), you can use something like Picasso to offload the Bitmap handling the correct way.

retain searchView state on orientation change in a Fragment

I am trying use the actionbarcompat (with the android support library) following the android developer's blog entry.
Basically, I am trying create a Fragment extending the ListFragment. I am using an ArrayAdapter for the listview. I was able to successfully integrate the actionbar compat with a search menu item and could get the search working as well.
I now want to retain the state of the fragment on orientation change as well. I haven't set the setRetainInstance(true) in my fragment. Inorder to retain the state of the search view, i tried the following:
save the text in the SearchView in onSaveInstanceState()
in onCreateView, retrieve the searchText if available
in onCreateOptionsMenu (which would be invoked on every orientation change), I am trying to set the search query to the SearchView instance mSearchView.setQuery(mSearchText, false);
There are 2 issues that I see with this approach:
the onQueryTextChange() is called twice on orientation change - once with the searchText that has been retained (because of mSearchView.setQuery(mSearchText, false);) and again, with an empty String value. This second call with the empty String value updates the list adapater to have all the items without any filtering. I am also not really sure why this is happening.
mSearchView.setQuery(mSearchText, false); isn't setting the query in the SearchView and is not visible in the UI as well (on orientation change, the search view is expanded by default and is focused without any text value though I have set the query).
Outline of my Fragment is as follows:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// create and initialize list adapter
....
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.plainlist, container, false);
if (savedInstanceState != null) {
mSearchText = savedInstanceState.getString(RetainDataKeySearchText, null);
}
return view;
}
#Override
public void onSaveInstanceState(Bundle outState) {
if (isAdded()) {
if (mSearchView != null) {
String searchText = mSearchView.getQuery().toString();
if (!TextUtils.isEmpty(searchText))
outState.putString(RetainDataKeySearchText, searchText);
}
}
super.onSaveInstanceState(outState);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.search_item_list, menu);
MenuItem searchItem = menu.findItem(R.id.menu_search);
mSearchView = (SearchView) MenuItemCompat.getActionView(searchItem);
mSearchView.setOnQueryTextListener(this);
if (!TextUtils.isEmpty(mSearchText))
mSearchView.setQuery(mSearchText, false);
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onQueryTextChange(String newText) {
// Called when the action bar search text has changed.
searchItems(newText);
return true;
}
#Override
public boolean onQueryTextSubmit(String searchText) {
return true;
}
private void searchItems(String searchText) {
// filter results and update the list adapter
}
The menu xml (search_item_list) file is as follows:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:sprinklr="http://schemas.android.com/apk/res-auto">
<item android:id="#+id/menu_search"
android:icon="#android:drawable/ic_menu_search"
android:title="#string/search"
android:orderInCategory="0"
sprinklr:showAsAction="ifRoom|collapseActionView"
sprinklr:actionViewClass="android.support.v7.widget.SearchView" />
</menu>
I would like to know if there is anything that I am missing or if there is a better alternate to retain the state of the SearchView (android.support.v7.widget.SearchView) on orientation change in a ListFragment with actionbarcompat.
As a workaround, replace your
mSearchView.setQuery(mSearchText, false);
with:
final String s = mSearchText;
mSearchView.post(new Runnable() {
#Override
public void run() {
mSearchView.setQuery(s, false);
}
});
It will set the saved string after the system has set the empty string.
I did it with AppCompatActivity rather than with Fragment. I used the equivalent solution as above but the search text wasn't visible even with the post on the search view. I added the menu item expansion before:
mSearchView.post(() -> {
searchItem.expandActionView();
mSearchView.setQuery(mSearchText, false);
mSearchView.clearFocus();
});

Preference Screen options (CheckBoxPreference and EditTextPreference) is not showing

I am new to android. My Preference Screen option is not showing. I am following below tutorial section "Preferences" and "Creating the Settings Activity"(https://wiki.oulu.fi/display/esde/List+views%2C+Intents%2C+Preferences+and+Notifications)
This is my SettingsActivity.java class
public class SettingsActivity extends Activity {
public static class SettingsFragment extends PreferenceFragment {
private SettingsFragment settingsFragment = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
settingsFragment = new SettingsFragment();
// Display the fragment as the main content.
getFragmentManager().beginTransaction()
.replace(android.R.id.content, settingsFragment)
.commit();
}
}
This is the settings for Preference
<?xml version="1.0" encoding="utf-8"?>
<PreferenceCategory android:title="#string/server_settings" >
</PreferenceCategory>
<CheckBoxPreference
android:defaultValue="false"
android:key="#+id/pref_check"
android:summaryOff="#string/pref_off"
android:summaryOn="#string/pref_on" >
</CheckBoxPreference>
<EditTextPreference
android:key="#+id/pref_edit"
android:defaultValue="#string/pref_default"
android:dialogTitle="#string/edit_text_pref">
</EditTextPreference>
In the main activity I have below method for launching SettingActivity class.
// launch the settings activity
public boolean onOptionsItemSelected(MenuItem item) {
startActivity(new Intent(this, SettingsActivity.class));
//return super.onOptionsItemSelected(item);
return true;
}
Also I have added below code under main activity, onCreate method to initialize the default values for the settings, from the preferences setting file
PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
Could you help me on this issue?

DialogBox in GWT isn't draggable or centred

I'm new to GWT programming. So far I have a DialogBox which is supposed to collect a login and a password, which can if required launch another DialogBox that allows someone to create a new account.
The first of these two DialogBoxes always appears at the top left of the browser screen, and can't be dragged, although part of the definition of a DialogBox is that it can be dragged. However, the second DialogBox can be dragged about the screen without any problem.
What I'd really like is for the first DialogBox to appear in the middle of the screen & be draggable, both of which I thought would happen automatically, but there's not.
So, what things can stop a DialogBox from being draggable? There is nothing on the RootPanel yet. Does that make a difference?
Code fragments available if they help, but perhaps this general outline is enough for some pointers.
Thanks
Neil
Use dialogBox.center() This will center your DialogBox in the middle of the screen. Normally a DialogBox is by default draggable.
Just tried it out and it doens't matter if your RootPanel is empty our not. When I just show the DialogBox on ModuleLoad it is draggable and it is centered. Probably the problem is situated somewhere else.
This is the example of google itself:
public class DialogBoxExample implements EntryPoint, ClickListener {
private static class MyDialog extends DialogBox {
public MyDialog() {
// Set the dialog box's caption.
setText("My First Dialog");
// DialogBox is a SimplePanel, so you have to set its widget property to
// whatever you want its contents to be.
Button ok = new Button("OK");
ok.addClickListener(new ClickListener() {
public void onClick(Widget sender) {
MyDialog.this.hide();
}
});
setWidget(ok);
}
}
public void onModuleLoad() {
Button b = new Button("Click me");
b.addClickListener(this);
RootPanel.get().add(b);
}
public void onClick(Widget sender) {
// Instantiate the dialog box and show it.
new MyDialog().show();
}
}
Here more information about the DialogBox.
Without seeing any of your code it's hard to tell what's going wrong. The following code works for me (ignore the missing styling...):
public void onModuleLoad() {
FlowPanel login = new FlowPanel();
Button create = new Button("create");
login.add(new TextBox());
login.add(new TextBox());
login.add(create);
create.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
final DialogBox box = new DialogBox();
FlowPanel panel = new FlowPanel();
Button close = new Button("close");
close.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
box.hide();
}
});
panel.add(new Label("some content"));
panel.add(close);
box.setWidget(panel);
box.center();
}
});
DialogBox firstBox = new DialogBox(false, true);
firstBox.setWidget(login);
firstBox.center();
}
Both boxes are draggable and shown in the center of your browser window.
Looks like you're overriding this method in Widget:
public void fireEvent(GwtEvent<?> event) {
if (handlerManager != null) {
handlerManager.fireEvent(event);
}
}
In Widget, handlerManager refers to a private HandlerManager.
Either add super.fireEvent(event) to your method or as you have done rename it.
Well, with vast amounts of trial and error I have found the problem, which was just this: I had a method in an object I'd based on DialogBox called fireEvent, which looked like this:
public void fireEvent(GwtEvent<?> event)
{
handlerManager.fireEvent(event);
}
Then, when a button was clicked on the DialogBox, an event would be created and sent off to the handlerManager to be fired properly.
And it turns out that if I change it to this (LoginEvent is a custom-built event):
public void fireEvent(LoginEvent event)
{
handlerManager.fireEvent(event);
}
... or to this ....
public void fireAnEvent(GwtEvent<?> event)
{
handlerManager.fireEvent(event);
}
the DialogBox is draggable. However, if the method begins with the line
public void fireEvent(GwtEvent<?> event)
then the result is a DialogBox which can't be dragged.
I'm a bit unsettled by this, because I can't fathom a reason why my choice of name of a method should affect the draggability of a DialogBox, or why using a base class (GwtEvent) instead of a custom class that extends it should affect the draggability. And I suspect there are dozens of similar pitfalls for a naive novice like me.
(Expecting the DialogBox to centre itself was simply my mistake.)