How to preserve Fragment List View Contents? - android

Preamble: I am using ActionBarSherlock, Target SDK is 17 (Android 4.2), Min SDK is 5 (Android 2.0)
Situation:
I've got a fragment in my app, which presents some kind of login. It allows the user to have several user accounts on device (because Android < 4.2 didn't have system support for that and our users seem to use that due to device sharing).
The fragment layout consists of a listview and on large-landscape also a button to add new accounts (otherwise via overflow menu available).
The listview is attached to a BaseAdapter-Derivate called "AccountAdapter", which gets the accounts from a database and creating corresponding child views per account via layoutinflater. There are 3 Possibilities: User provided both Login and Password / User provided only login / User provided nothing. Therefore, there are 3 different Layouts for those cases, where the missing data is requested via EditText-Elements and stored data is shown via TextView. Also, the layouts with missing data provide a checkbox for store the missing data and a submit-button. If all data is provided, the onclicklistener for the missing submit button gets directly attached to the account root view.
The onclicklistener messages the entered data to the network code class and modifys the adapter mode; after that, the adapter only shows the selected entry, but with the "progress" view, to visualize the current action to the user ("User XXX is being logged in, please stand by...").
This already works well.
Problem:
On orientation changes, all entered data gets lost. Entered login data, passwords, information about if the login data should be stored.
Layouts:
<!-- layout/main.xml -->
<?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:orientation="horizontal" >
<FrameLayout
android:id="#id/main_fragment_content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<!-- layout-large-land/main.xml -->
<?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:orientation="horizontal" >
<FrameLayout
android:id="#id/main_fragment_sidebar"
android:layout_width="#dimen/main_sidebar_width"
android:layout_height="match_parent" />
<FrameLayout
android:id="#id/main_fragment_content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<!-- layout/fragment_login.xml -->
<?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" >
<ListView
android:id="#id/fragment_login_accountlist"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
</RelativeLayout>
<!-- layout-large-land/fragment_login.xml -->
<?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" >
<Button
android:id="#id/fragment_login_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text="#string/string_fragment_login" />
<ListView
android:id="#id/fragment_login_accountlist"
android:layout_width="#dimen/fragment_login_accountlist_width"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" >
</ListView>
</RelativeLayout>
<!-- layout/view_login_account_new.xml -->
<?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" >
<ImageView
android:id="#id/view_login_account_profileimage"
android:layout_width="#dimen/view_login_account_profileimage_width"
android:layout_height="#dimen/view_login_account_profileimage_height"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:contentDescription="#string/string_view_login_account_profileimage_contentdescription"
android:scaleType="fitCenter"
android:src="#drawable/img_kb" />
<EditText
android:id="#id/view_login_account_username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_toRightOf="#id/view_login_account_profileimage"
android:ems="10"
android:hint="#string/string_view_login_account_username_hint"
android:inputType="text" >
<requestFocus />
</EditText>
<EditText
android:id="#id/view_login_account_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#id/view_login_account_username"
android:layout_alignParentRight="true"
android:layout_below="#id/view_login_account_username"
android:ems="10"
android:hint="#string/string_view_login_account_password_hint"
android:inputType="textPassword" />
<CheckBox
android:id="#id/view_login_account_storecredentials"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="#id/view_login_account_password"
android:layout_toRightOf="#id/view_login_account_profileimage"
android:text="#string/string_view_login_account_storecredentials_text" />
<Button
android:id="#id/view_login_account_submit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="#id/view_login_account_storecredentials"
android:text="#string/string_view_login_account_submit_text" />
</RelativeLayout>
<!-- layout/view_login_account_progress.xml -->
<?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" >
<ImageView
android:id="#id/view_login_account_profileimage"
android:layout_width="#dimen/view_login_account_profileimage_width"
android:layout_height="#dimen/view_login_account_profileimage_height"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:contentDescription="#string/string_view_login_account_profileimage_contentdescription"
android:scaleType="fitCenter"
android:src="#drawable/img_kb" />
<TextView
android:id="#id/view_login_account_username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_toRightOf="#id/view_login_account_profileimage"
android:ems="10"
>
</TextView>
<TextView
android:id="#id/view_login_account_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#id/view_login_account_username"
android:layout_alignParentRight="true"
android:layout_below="#id/view_login_account_username"
android:ems="10"
android:text="#string/string_view_login_account_progress_text" />
</RelativeLayout>
<!-- layout/view_login_account_stored_password.xml -->
<?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" >
<ImageView
android:id="#id/view_login_account_profileimage"
android:layout_width="#dimen/view_login_account_profileimage_width"
android:layout_height="#dimen/view_login_account_profileimage_height"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:contentDescription="#string/string_view_login_account_profileimage_contentdescription"
android:scaleType="fitCenter"
android:src="#drawable/img_kb" />
<TextView
android:id="#id/view_login_account_username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_toRightOf="#id/view_login_account_profileimage"
android:ems="10"
>
</TextView>
<TextView
android:id="#id/view_login_account_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#id/view_login_account_username"
android:layout_alignParentRight="true"
android:layout_below="#id/view_login_account_username"
android:ems="10"
android:text="#string/string_view_login_account_password_text"
/>
</RelativeLayout>
<!-- layout/view_login_account_stored_username.xml -->
<?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" >
<ImageView
android:id="#id/view_login_account_profileimage"
android:layout_width="#dimen/view_login_account_profileimage_width"
android:layout_height="#dimen/view_login_account_profileimage_height"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:contentDescription="#string/string_view_login_account_profileimage_contentdescription"
android:scaleType="fitCenter"
android:src="#drawable/img_kb" />
<TextView
android:id="#id/view_login_account_username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_toRightOf="#id/view_login_account_profileimage"
android:ems="10"
android:hint="#string/string_view_login_account_username_hint" >
<requestFocus />
</TextView>
<EditText
android:id="#id/view_login_account_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#id/view_login_account_username"
android:layout_alignParentRight="true"
android:layout_below="#id/view_login_account_username"
android:ems="10"
android:hint="#string/string_view_login_account_password_hint"
android:inputType="textPassword" />
<CheckBox
android:id="#id/view_login_account_storecredentials"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="#id/view_login_account_password"
android:layout_toRightOf="#id/view_login_account_profileimage"
android:text="#string/string_view_login_account_storecredentials_text" />
<Button
android:id="#id/view_login_account_submit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="#id/view_login_account_storecredentials"
android:text="#string/string_view_login_account_submit_text" />
</RelativeLayout>
Code:
The code both doesn't implement onSaveInstanceState and onConfigurationChange yet.
(whole quotation would be too long imho, > 1.000 lines of code)
public class MessengerActivity extends SherlockFragmentActivity {
// -------------------------------------------------------------------------
FrameLayout fragmentSidebar = null;
FrameLayout fragmentContent = null;
Content content = null;
// -------------------------------------------------------------------------
boolean hasSidebar = false;
// -------------------------------------------------------------------------
public void onCreate(Bundle savedInstanceState) {
// ---------------------------------------------------------------------
super.onCreate(savedInstanceState);
// ---------------------------------------------------------------------
content = Content.getInstance(this);
// ---------------------------------------------------------------------
setContentView(R.layout.main);
// ---------------------------------------------------------------------
captureFragmentViews();
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
if (savedInstanceState == null) {
// -----------------------------------------------------------------
gotoLogin();
// -----------------------------------------------------------------
}
else {
// -----------------------------------------------------------------
// -----------------------------------------------------------------
}
// ---------------------------------------------------------------------
}
// -------------------------------------------------------------------------
// Disabled through android manifest at the moment
#Override
public void onConfigurationChanged(Configuration newConfig) {
// ---------------------------------------------------------------------
super.onConfigurationChanged(newConfig);
// ---------------------------------------------------------------------
Log.d(getClass().getSimpleName(), "onConfigurationChanged");
// ---------------------------------------------------------------------
}
// -------------------------------------------------------------------------
public void captureFragmentViews() {
// ---------------------------------------------------------------------
fragmentSidebar = (FrameLayout) findViewById(R.id.main_fragment_sidebar);
fragmentContent = (FrameLayout) findViewById(R.id.main_fragment_content);
// ---------------------------------------------------------------------
if ((fragmentSidebar != null) && (fragmentContent != null)) {
hasSidebar = true;
}
else {
hasSidebar = false;
}
// ---------------------------------------------------------------------
}
// -------------------------------------------------------------------------
public void gotoLogin() {
// ---------------------------------------------------------------------
Fragment fragment = SherlockFragment.instantiate(this,
LoginFragment.class.getName());
// ---------------------------------------------------------------------
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
if (hasSidebar) {
ft.add(R.id.main_fragment_content, fragment);
fragmentSidebar.setVisibility(View.GONE);
}
else {
ft.add(R.id.main_fragment_content, fragment);
}
// ---------------------------------------------------------------------
ft.commit();
getSupportFragmentManager().executePendingTransactions();
// ---------------------------------------------------------------------
}
// -------------------------------------------------------------------------
public void gotoSignup() {
// TODO Auto-generated method stub
}
// -------------------------------------------------------------------------
public void gotoContactList(int filterId) {
// TODO Auto-generated method stub
}
// -------------------------------------------------------------------------
public void gotoConversation(int userId) {
// TODO Auto-generated method stub
}
// -------------------------------------------------------------------------
public void gotoOnlineStatusList(int categoryId) {
// TODO Auto-generated method stub
}
// -------------------------------------------------------------------------
public void gotoSettings(int categoryId) {
// TODO Auto-generated method stub
}
// -------------------------------------------------------------------------
}
I check for whether savedInstanceState is set or not in the main activity, so my activity is already "prepared" in terms of fragment recreation.
Fragment checks for whether the adapter already exists or not before creating and attaching it to the listview.
But: As far as my understanding is, even if the "recreated" fragment use the same Adapter, "by default" all getViews() get recalled and therefore create a new instance of the view with "resetted" contents.
The AccountAdapter gets dedicated "Account"-Objects with user-id, username, password from the database. Also, "Account" could be extended to hold additional data, like to cache the view.
My idea was to implement a getView like this:
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
// ---------------------------------------------------------------------
final Account account = (Account) getItem(position);
View view = null;
// ---------------------------------------------------------------------
if (account == null) {
return view;
}
// ---------------------------------------------------------------------
if (account.view != null) {
return account.view;
}
// ---------------------------------------------------------------------
[...]
}
But then I noticed, that the AccountAdapter didn't survive the recreation, Android re-instantiates the LoginFragment class.
What I need:
How to recover the data from the listview content formulars / how to preserve the AccountAdapter and its associated views
Tips on how to optimize and improve my architectural design

It is not clear from your code if you add a Fragment every time the onCreate() method of your Activity get's called.
You should add a Fragment or the first Fragment only when the Activity get's created for the first time .
if(savedInstanceState==null){
addFragment();
}
if this is not null your Activity gets re-created, and it will also re-add your previous Fragments. Evan if you have more Fragments in the backstack they will all be put back in your Activity.
To keep the data in your fragments, you should either use setRetainInstance(true); on your Fragments onCreate() method, or use onSaveInstanceState(Bundle bundle) to save the specific data.

Related

Dynamically adding fragments below an existing fragment in a LinearLayout

I am making an activity which has a section for comments based on addresses inputed by the user.
The user will add a new comments section by pressing a button. This is a non fixed number of sections, so I have initially added this section as a fragment in the xml.
I have an onClick function that adds another fragment to the linearlayout.
My problem is that the new fragments always add to the top of the linearlayout , i.e. above the existing fragment/fragments (i.e. the new fragment will push all the other fragments down).
How can I add the new fragment so that it displays below the existing fragment?
Code in .java file:
public class SpecialReportAdden extends ActionBarActivity {
int numOfFragments;
LinearLayout addenHolder;
TextView report;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_special_report_adden);
numOfFragments=1;
Button addenSave = (Button)findViewById(R.id.btnAddendumSave);
Button addenAddComment = (Button)findViewById(R.id.btnAddendumAddComment);
addenHolder =(LinearLayout)findViewById(R.id.AddenLinLayHolder);
addenSave.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//this should save all comments including those added in dynamically produced fragments
//save database
Intent i = new Intent (SpecialReportAdden.this, MenuPage.class);
startActivity(i);
}
});
addenAddComment.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.i("number of Fragments at start of OnClick", Integer.toString(numOfFragments));
Fragment newAddenFrag = addNewfragment(numOfFragments);
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.AddenLinLayInnerHolder, newAddenFrag);
ft.addToBackStack(null);
ft.commit();
numOfFragments++;
Log.i("number of Fragments updated", Integer.toString(numOfFragments));
}
});
}
public Fragment addNewfragment(int number) {
AddendumLinInputFragment adden = new AddendumLinInputFragment();
TextView tx = (TextView) findViewById(R.id.txtVAddendumFragReportNum);
tx.setText("Report "+number+" :");
tx.setTextColor(Color.BLACK);
TextView address = (TextView)findViewById(R.id.txtVAddendumFragAddress);
address.setText("A new address");
address.setTextColor(Color.BLUE);
return adden;
}
xml file for the .java activity
<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" android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context="com.example.danielt.pestcontrol.SpecialReportAdden"
android:id="#+id/RellayAddenComments">
<TextView
android:id="#+id/txtVAddendumTitle" android:text="Service Report Addendum" android:textStyle="bold" android:layout_centerHorizontal="true" android:elegantTextHeight="true" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dp"/>
<TextView
android:id="#+id/txtVAddendumTechName"
android:layout_below="#+id/txtVAddendumTitle"
android:layout_marginTop="16dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Technician Name: "
android:textSize="18sp"
/>
<TextView
android:id="#+id/txtVAddendumDate"
android:layout_below="#+id/txtVAddendumTechName"
android:layout_marginTop="16dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Date: "
android:textSize="18sp"
/>
<ScrollView
android:id="#+id/scrlVAddendum"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/txtVAddendumDate">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/AddenLinLayHolder"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/AddenLinLayInnerHolder"
android:orientation="vertical">
<fragment
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:name="com.example.danielt.pestcontrol.AddendumLinInputFragment"
android:id="#+id/addendum1CommentsFragment"
android:layout_below="#+id/txtVAddendum1Date"
android:layout_marginTop="24dp"
tools:layout="#layout/fragment_addendum_lin_input" />
</LinearLayout>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add another Addendum Comment"
android:id="#+id/btnAddendumAddComment"
android:layout_below="#+id/scrlVAddendum"
android:layout_centerHorizontal="true"
android:layout_marginTop="36dp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Save / Update Comments"
android:id="#+id/btnAddendumSave"
android:layout_below="#+id/btnAddendumAddComment"
android:layout_centerHorizontal="true"
android:layout_marginTop="44dp" />
</LinearLayout>
</ScrollView>
I havent added the fragment code but I will if someone wants to see it.
Thanks for any help.
You don't need fragment to hold only comment view. Just inflate new comment view and add it to the parent view.
LayoutInflater inflater = LayoutInflater.from(context);
View inflatedLayout= inflater.inflate(R.layout.yourLayout, container, false);
container.addView(inflatedLayout);
Where container is a view that hold all comments.
Regarding adding fragments, according to Fragments documentation:
If you're adding multiple fragments to the same container, then the
order in which you add them determines the order they appear in the
view hierarchy
Therefore if it's behave different, it could be related to OS version or bug :)

How to create a Button in the camera view in vuforia?

I am using Vuforia AR sdk and want to create a button on the camera preview on the screen.
I cannot figure out where and how to add the button.
I have edit the camera_overlay_udt.xml like this.. In my layout design i have placed back button and listview.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/camera_overlay_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="#+id/headerLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="#drawable/header"
android:orientation="horizontal" >
<ImageButton
android:id="#+id/backButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:background="#android:color/transparent"
android:src="#drawable/back" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="match_parent" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Swipart"
android:textColor="#color/white"
android:textSize="18dp"
android:textStyle="bold" />
<ImageButton
android:id="#+id/arcstarButton"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_centerInParent="true"
android:layout_marginRight="10dp"
android:background="#android:color/transparent"
android:src="#drawable/star_button" />
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:id="#+id/favListingLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/headerLayout"
android:gravity="top"
android:orientation="horizontal"
android:visibility="visible" >
<ListView
android:id="#+id/favlist"
android:layout_width="120dp"
android:layout_height="match_parent"
android:layout_marginBottom="50dp"
android:layout_marginLeft="7dp"
android:cacheColorHint="#00000000" />
</LinearLayout>
<LinearLayout
android:id="#+id/bottom_bar"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_marginRight="10dp"
android:background="#color/overlay_bottom_bar_background"
android:gravity="center_vertical"
android:orientation="horizontal"
android:visibility="visible"
android:weightSum="1" >
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="#color/overlay_bottom_bar_separators" />
<ImageButton
android:id="#+id/camera_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="#null"
android:contentDescription="#string/content_desc_camera_button"
android:onClick="onCameraClick"
android:paddingBottom="10dp"
android:paddingTop="10dp"
android:src="#drawable/camera_button_background" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_above="#id/bottom_bar"
android:background="#color/overlay_bottom_bar_separators" />
</RelativeLayout>
after that please Edit that ImageTargets.java class
private void addOverlayView(boolean initLayout) {
// Inflates the Overlay Layout to be displayed above the Camera View
LayoutInflater inflater = LayoutInflater.from(this);
mUILayouts = (RelativeLayout) inflater.inflate(
R.layout.camera_overlay_udt, null, false);
mUILayouts.setVisibility(View.VISIBLE);
// If this is the first time that the application runs then the
// uiLayout background is set to BLACK color, will be set to
// transparent once the SDK is initialized and camera ready to draw
if (initLayout) {
mUILayouts.setBackgroundColor(Color.TRANSPARENT);
}
// Adds the inflated layout to the view
addContentView(mUILayouts, new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
// Gets a reference to the bottom navigation bar
mBottomBar = mUILayouts.findViewById(R.id.bottom_bar);
// Gets a reference to the Camera button
mCameraButton = mUILayouts.findViewById(R.id.camera_button);
mCameraButton.setVisibility(View.GONE);
favButton = (ImageButton) mUILayouts.findViewById(R.id.arcstarButton);
listview = (ListView) mUILayouts.findViewById(R.id.favlist);
backButton = (ImageButton) mUILayouts.findViewById(R.id.backButton);
backButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View paramView) {
// TODO Auto-generated method stub
finish();
}
});
listview.setVisibility(View.GONE);
galleryList = SendFile.getFavourites();
if (galleryList != null) {
gridviewAdapter = new GridviewAdapter(ImageTargets.this);
listview.setAdapter(gridviewAdapter);
}
favButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (galleryList != null && galleryList.size() > 0) {
if (listview.getVisibility() == View.GONE) {
listview.setVisibility(View.VISIBLE);
} else {
listview.setVisibility(View.GONE);
}
} else {
Toast.makeText(ImageTargets.this, "Favourites not fond",
Toast.LENGTH_LONG).show();
}
}
});
listview.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> paramAdapterView,
View paramView, int positon, long paramLong) {
SendFile.setFavourite(galleryList.get(positon));
Intent intent = new Intent(ImageTargets.this,
LoadingScreen.class);
Bundle bundle = new Bundle();
bundle.putInt("x", x_Axis);
bundle.putInt("y", y_Axis);
intent.putExtras(bundle);
startActivity(intent);
finish();
}
});
showDialogHandler = new Handler() {
public void handleMessage(Message msg) {
String aResponse = msg.getData().getString("message");
if ((null != aResponse)) {
// ALERT MESSAGE
Toast.makeText(getBaseContext(),
"Server Response: " + aResponse, Toast.LENGTH_SHORT)
.show();
showAlertDialog(aResponse);
} else {
// ALERT MESSAGE
Toast.makeText(getBaseContext(),
"Not Got Response From Server.", Toast.LENGTH_SHORT)
.show();
}
};
};
loadingDialogHandler.captureButtonContainer = mUILayouts
.findViewById(R.id.camera_button);
mUILayouts.bringToFront();
}
They showing there layouts using handlers
Start you camera preview in a normal way. Place a layout on top of it with transparent background like this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:background="#ff000000"
android:layout_height="match_parent">
<ImageView
android:id="#+id/start_image_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="5dp"
android:scaleType="fitXY"
android:layout_weight="1"
android:src="#drawable/scan_image"/>
</RelativeLayout>
In java file, you can add this layout like this:
private View mStartupView;
mStartupView = getLayoutInflater().inflate(
R.layout.startup_screen, null);
// Add it to the content view:
addContentView(mStartupView, new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
This way you will get to see your button on top of camera preview. Hope it helps
You can add buttons in cameraoverlay layout which is in layout folder and you can initialize buttons in initAR function which is in mainactivity.
Step 1: Add the button in the camera_overlay.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/camera_overlay_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ProgressBar
style="#android:style/Widget.ProgressBar"
android:id="#+id/loading_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="18dp"
android:layout_marginTop="51dp"
android:text="Button" />
</RelativeLayout>
Step 2: Edit the ImageTargets.java class
private static final String LOGTAG = "ImageTargets";
private Button b1;
Step 3: Modify the initApplicationAR() function of ImageTargets.java class
private void initApplicationAR()
{
// Create OpenGL ES view:
int depthSize = 16;
int stencilSize = 0;
boolean translucent = Vuforia.requiresAlpha();
mGlView = new SampleApplicationGLView(this);
mGlView.init(translucent, depthSize, stencilSize);
mRenderer = new ImageTargetRenderer(this, vuforiaAppSession);
mRenderer.setTextures(mTextures);
mGlView.setRenderer(mRenderer);
b1 = (Button) findViewById(R.id.button1);
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
b1.setVisibility(View.GONE);
}
});
}
Now lay back and watch your button disappear on a click!
Although it's a long time since the post.. yet I found one article.. wherein you can have the desired thing..
Ref: https://medium.com/nosort/adding-views-on-top-of-unityplayer-in-unityplayeractivity-e76240799c82
Solution:
Step1: Make a custom layout XML file (vuforia_widget_screen.xml). For example, button has been added.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/main_layout">
<FrameLayout
android:id="#+id/unity_player_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<Button
android:id="#+id/back_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="#null"
android:text="#string/welcome" />
</FrameLayout>
Step 2: Make following changes in the UnityPlayerActivity.java
Replace "setContentView(mUnityPlayer);" with
setContentView(R.layout.vuforia_widget_screen);
FrameLayout frameLayout = findViewById(R.id.unity_player_layout);
frameLayout.addView(mUnityPlayer.getView());
-> For anyone, who will face the issue in future. :)

Populate fragment with Bundle arguments

I have a listFragment to display a list,
when we click on the list I want to display a Fragment with the details of the clicked element. I'm doing this with dynamic fragment.
My Problem is about the displaying of my detailsFragment. (cf picture).
I'm supposed to have the "designation" and other information .
I only have a part of my DetailsFragment XML.
However I checked the bundle with the debug mode and the communication is OK.
So Why is there a problem for the displaying of this fragment?
Principal Host Activity
public void onListItemClick(int id) {
F_Outils_details detail_frag = (F_Outils_details)
getFragmentManager().findFragmentById(R.id.listFragment2);
if (detail_frag != null) {
// If article frag is available, we're in two-pane layout...
// Call a method in the ArticleFragment to update its content
detail_frag.setDetails((int)id);
}
else {
// If the frag is not available, we're in the one-pane layout and must swap frags...
F_Outils_details detail_frag_new = new F_Outils_details();
Bundle args = new Bundle();
args.putInt("outil",(int) id);
detail_frag_new.setArguments(args);
FragmentTransaction transaction =getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
transaction.replace(R.id.fragment_container1, detail_frag_new);
transaction.addToBackStack(null);
transaction.commit();
}
DetailFragmentActivity
public class F_Outils_details extends Fragment {
ArrayList detail_outils=new ArrayList();
Outil outil;
TextView id_outil;
TextView designation;
TextView date_location;
View a;
ArrayList liste_outils;
int mCurrentPosition=-1;
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
return inflater.inflate(R.layout.f_outils_details, container, false);
}
#Override
public void onStart() {
super.onStart();
// During startup, check if there are arguments passed to the fragment.
// onStart is a good place to do this because the layout has already been
// applied to the fragment at this point so we can safely call the method
// below that sets the article text.
Bundle args = getArguments();
//si il y a pas d'arguments
if (args != null) {
setDetails(args.getInt("outil"));
} else if (mCurrentPosition != -1) {
System.out.println("mccurent posit");
// Set article based on saved instance state defined during onCreateView
setDetails(mCurrentPosition);
}
}
//methode qui va changer le texte !
public void setDetails(int id){
if(id==-1){
designation.setText("");
date_location.setText("");
}
else{
//on recupere l'outil
DB_Locoutils dbLocoutils=DB_Locoutils.getInst();
liste_outils=dbLocoutils.getOutils();
outil =(Outil) liste_outils.get((int) id);
System.out.println("**************"+outil.getDesignation());
//id_outil=(TextView) getView().findViewById(R.id.id_outil);
designation=(TextView) getActivity().findViewById(R.id.designation);
date_location=(TextView) getActivity().findViewById(R.id.date_location);
if(designation!=null){
System.out.println("DESIGNATION OK");
}
//id_outil.setText(outil.getIdOutil());
designation.setText(outil.getDesignation());
date_location.setText(outil.getDateLocation());
}
}
}
XML detailFragment
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/titre"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textStyle="bold"
android:textSize="20dp"
android:text="Details" />
<TextView
android:id="#+id/id_outil"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:text="id outil"
/>
<TextView
android:id="#+id/designation"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:text="designation"
/>
<TextView
android:id="#+id/refClient"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:text="ref Client"
/>
<TextView
android:id="#+id/date_location"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:text="date location"
/>
I think the problem is that you have all your TextViews with the height attributes to match_parent. This indicates that your first item take all the parent height and the others stay behind. Try to use this layout instead:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/titre"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textStyle="bold"
android:textSize="20dp"
android:text="Details" />
<!-- as the item above, set the height to wrap_content -->
<TextView
android:id="#+id/id_outil"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="id outil"
/>
<TextView
android:id="#+id/designation"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="designation"
/>
<TextView
android:id="#+id/refClient"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="ref Client"
/>
<TextView
android:id="#+id/date_location"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="date location"
/>
</LinearLayout>
Hope this helps and you will have the expected result.

Android layout help, missing elements

I’m trying to creating a layout that contains a "SurfaceView" at the top with a horizontal toolbar that is section into 3 segments in the bottom, however my SurfaceView which contains camera preview is only the only element that is showing. Please point out the error in my layout xml or provide me the similar layout xml, Thanks.
Below is my layout & updates based on user recommendations
Attempt # 1 (RelativeLayout as root):
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LayoutForPreview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:screenOrientation="portrait" >
<SurfaceView
android:id="#+id/surfaceViewBarcodeScanner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/linearLayoutToolbar"
android:layout_gravity="top"
android:scaleType="fitXY" />
<LinearLayout
android:id="#+id/linearLayoutToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:src="#drawable/scanner_bottom_left" />
<ImageView
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.68"
android:scaleType="fitXY"
android:src="#drawable/scanner_bottom_center_toolbar" />
<ImageView
android:id="#+id/imageView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:src="#drawable/scanner_bottom_right_landscape_button" />
</LinearLayout>
</RelativeLayout>
Below is my desired GUI look:
Attempt #1 Result , device snapshot , which only shows the SurfaceView:
Snapshot of eclipse GUI tool, which shows what the layout should look like.
Attempt # 2 (LinearLayout as root):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LayoutForPreview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:screenOrientation="portrait" >
<SurfaceView
android:id="#+id/surfaceViewBarcodeScanner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:scaleType="fitXY"
android:layout_weight="1" />
<LinearLayout
android:id="#+id/linearLayoutToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="bottom" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:src="#drawable/scanner_bottom_left" />
<ImageView
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.68"
android:scaleType="fitXY"
android:src="#drawable/scanner_bottom_center_toolbar" />
<ImageView
android:id="#+id/imageView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:src="#drawable/scanner_bottom_right_landscape_button" />
</LinearLayout>
</LinearLayout>
Attempt #2 , Result , Device snapshot :
Issues:
1) Toolbar appears on top rather than on bottom
2) Camera preview freezes & app crashes. For some reason LinearLayout causes the Camera error 1001 , and I think its related to preview sizes.
Attempt #3 (Add toolbar programmatically to either Relative or Linear layout in activity onCreate).
LinearLayout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LayoutForPreview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:screenOrientation="portrait" >
<SurfaceView
android:id="#+id/surfaceViewBarcodeScanner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:scaleType="fitXY"
android:layout_weight="1" />
</LinearLayout>
Toolbar defined in separate XML added later via Java code:
<?xml version="1.0" encoding="UTF-8"?>
<!-- LinearLayout that contains toolbar that is divided into 3 sections horizontally , layout_below="#+id/BarcodeScannerFrame-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linearLayoutToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:orientation="horizontal" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:src="#drawable/scanner_bottom_left" />
<ImageView
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.68"
android:scaleType="fitXY"
android:src="#drawable/scanner_bottom_center_toolbar" />
<ImageView
android:id="#+id/imageView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:src="#drawable/scanner_bottom_right_landscape_button" />
</LinearLayout>
onCreate,onResume,other relevant code snippets of my activity only, the LinearLayout toolbar is added to Linear or Relative layout at runtime:
//import not included
public class ScanVinFromBarcodeActivity extends Activity {
// camera object that is used globally in this activity and also passed
// reference to PreviewSurface inner class
private Camera globalCamera;
private int cameraId = 0;
// bitmap that would created after picture is taken and converted from
// camera bytes
private Bitmap bmpOfTheImageFromCamera = null;
// global flag whether a camera has been detected
private boolean isThereACamera = false;
// layout for this activity
private LinearLayout RelativeLayoutBarcodeScanner= null;
// CameraPreview extends SurfaceView displays preview of images from the
// Camera
private CameraPreview newCameraPreview = null;
// used to inflate the xml layout
private SurfaceView surfaceViewBarcodeScanner = null;
private boolean cameraPreviewing = false;
// this continueToAutomaticallyDecode flag is initially set to TRUE, but
// will be set to FALSE on the first successful decode OR when a crucial
// method in the code process fails or throws an exception
private volatile boolean continueToAutomaticallyDecode = true;
// global flag used to indicate picture taking & decoding is in progress
private volatile boolean takingPictureAndDecodeInprogress = false;
// Bitmap options for bitmap creation from camera picture
BitmapFactory.Options options = null;
// used for samsung galaxy s devices only
private Matrix rotationMatrix90CounterClockWise = null;
// Reader is class from zxing used to decode barcodes
Reader reader = null;
// DecodeHintType hashtable is used to provide help to the zxing Reader
// class
Hashtable<DecodeHintType, Object> decodeHints = null;
//
private boolean onTouchEvent = true;
//
private OrientationEventListener orientationEventListener = null;
// 1 means the screen is PORTRAIT and 2 means screen is LANDSCAPE
private int latestScreenOrientation = 1;
//
Camera.Parameters Flash = null;
//
private String globalVIN = null;
//
private Handler handler = null;
//
private LinearLayout barcodeVinScannerToolbar = null;
public boolean isContinueToAutomaticallyDecode() {
return continueToAutomaticallyDecode;
}
public void setContinueToAutomaticallyDecode(
boolean continueToAutomaticallyDecode) {
this.continueToAutomaticallyDecode = continueToAutomaticallyDecode;
}
public boolean isTakingPictureAndDecodeInprogress() {
return takingPictureAndDecodeInprogress;
}
public void setTakingPictureAndDecodeInprogress(
boolean takingPictureAndDecodeInprogress) {
this.takingPictureAndDecodeInprogress = takingPictureAndDecodeInprogress;
}
/*
* This method , finds FEATURE_CAMERA, opens the camera, set parameters ,
* add CameraPreview to layout, set camera surface holder, start preview
*/
#SuppressLint("InlinedApi")
private void initializeGlobalCamera() {
try {
if (!getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA)) {
Toast.makeText(this, "No camera on this device",
Toast.LENGTH_LONG).show();
} else { // check for front camera ,and get the ID
cameraId = findFrontFacingCamera();
if (cameraId < 0) {
Toast.makeText(this, "No front facing camera found.",
Toast.LENGTH_LONG).show();
} else {
Log.d("ClassScanViewBarcodeActivity",
"camera was found , ID: " + cameraId);
// camera was found , set global camera flag to true
isThereACamera = true;
// OPEN
globalCamera = getGlobalCamera(cameraId);
// parameters auto focus
globalCamera.getParameters().setFocusMode(
Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
// set picture format to JPEG, everytime makesure JPEg
globalCamera.getParameters().setPictureFormat(
ImageFormat.JPEG);
autoFocusSetupForBarcode(globalCamera);
/*
* START early setup variables & setting used in
* jpegCallback in order to optimize the jpegCallback code
*/
options = new BitmapFactory.Options();
// option set for down sampling he captured image taken from
// the camera in order to MemoryOutOfBounds exception
options.inSampleSize = 4;
// image quality rather than speed in order to achieve early
// barcode detection & decode
options.inPreferQualityOverSpeed = false;
// Samsung galaxy S only , rotate to correct orientation
// ,and capture only the image within the guidance rectangle
rotationMatrix90CounterClockWise = new Matrix();
rotationMatrix90CounterClockWise.postRotate(90);
// early variable used by zxing to decode method
decodeHints = new Hashtable<DecodeHintType, Object>();
decodeHints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
decodeHints.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE);
decodeHints.put(DecodeHintType.ASSUME_CODE_39_CHECK_DIGIT,
Boolean.TRUE);
reader = new MultiFormatReader();
turnOnFlashlight(globalCamera);
// pass surfaceView to CameraPreview
newCameraPreview = new CameraPreview(this, globalCamera) {
#Override
public boolean onTouchEvent(MotionEvent event) {
Log.d("ClassScanViewBarcodeActivity",
" onTouchEvent(MotionEvent event) ");
onTouchEvent = true;
globalCamera
.autoFocus(autoFocusCallbackForAutomaticScan);
return super.onTouchEvent(event);
}
};
// pass CameraPreview to Layout
RelativeLayoutBarcodeScanner.addView(newCameraPreview);
// give reference SurfaceView to camera object
globalCamera.setPreviewDisplay(surfaceViewBarcodeScanner
.getHolder());
// PREVIEW
if (cameraPreviewing != true) {
globalCamera.startPreview();
}
Log.d("ClassScanViewBarcodeActivity",
"camera opened & previewing");
}
}// end else ,check for front camera
}// end try
catch (Exception exc) {
// in case of exception release resources & cleanup
if (globalCamera != null) {
globalCamera.stopPreview();
cameraPreviewing = false;
globalCamera.setPreviewCallback(null);
globalCamera.release();
globalCamera = null;
options = null;
rotationMatrix90CounterClockWise = null;
reader = null;
}
Log.d("ClassScanViewBarcodeActivity initializeGlobalCamera() exception:",
exc.getMessage());
exc.printStackTrace();
}// end catch
}// end ini
/* this method detect whether the camera flashlight a.k.a torch feature is available to be turned on then turns on the light*/
public void turnOnFlashlight(Camera camera) {
Log.d("ClassScanViewBarcodeActivity",
"turnOnFlashlight(Camera camera )");
boolean flag = false;
Context context = null;
if (camera != null) {
Log.d("ClassScanViewBarcodeActivity",
"turnOnFlashlight() , FEATURE_CAMERA_FLASH: " + flag);
context = RelativeLayoutBarcodeScanner.getContext();
if (context != null) {
flag = context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA_FLASH);
if (flag) {
Flash = camera.getParameters();
Flash.setFlashMode("torch");
camera.setParameters(Flash);
}// end if camera feature is available
else {
Log.d("ClassScanViewBarcodeActivity",
"turnOnFlashlight() , FEATURE_CAMERA_FLASH: "
+ flag);
}
}// end if context not null
}// end camera not null
}// end turnOnFlashlight(Camera camera )
// onCreate, instantiates layouts & surfaceView used for video preview
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_barcode_vin_scanner);
Log.d("ClassScanViewBarcodeActivity", "onCreate ");
// create surfaceView for previewing of camera image
RelativeLayoutBarcodeScanner = (LinearLayout) findViewById(R.id.LayoutForPreview);
surfaceViewBarcodeScanner = (SurfaceView) findViewById(R.id.surfaceViewBarcodeScanner);
barcodeVinScannerToolbar = (LinearLayout) findViewById(R.id.linearLayoutToolbar);
initializeGlobalCamera();
//*****TOOLBAR IS ADDED*****
if (RelativeLayoutBarcodeScanner!=null && barcodeVinScannerToolbar!=null)
{
//surfaceViewBarcodeScanner.addChildrenForAccessibility(list);
RelativeLayoutBarcodeScanner.addView(barcodeVinScannerToolbar);
}
// instantiate orientationEventListener
orientationEventListener = new OrientationEventListener(this,
SensorManager.SENSOR_DELAY_NORMAL) {
#Override
public void onOrientationChanged(int arg0) {
/*
latestScreenOrientation = ScreenUtility
.getScreenOrientation(RelativeLayoutBarcodeScanner.getContext());
Log.d("ClassScanViewBarcodeActivity",
"latestScreenOrientation: " + latestScreenOrientation);
if (orientationEventListener.canDetectOrientation()) {
orientationEventListener.enable();
Log.d("ClassScanViewBarcodeActivity",
"enabled orientationEventListener: "
+ String.valueOf(orientationEventListener
.canDetectOrientation()));
} else {
Log.d("ClassScanViewBarcodeActivity",
"enabled orientationEventListener: "
+ String.valueOf(orientationEventListener
.canDetectOrientation()));
}
*/
}
};
handler = new Handler();
}// end onCreate
#Override
protected void onResume() {
Log.d("ClassScanViewBarcodeActivity, onResume() globalCamera:",
String.valueOf(globalCamera));
initializeGlobalCamera();
//*****TOOLBAR IS ADDED*****
if (RelativeLayoutBarcodeScanner!=null && barcodeVinScannerToolbar!=null)
{
//surfaceViewBarcodeScanner.addChildrenForAccessibility(list);
RelativeLayoutBarcodeScanner.addView(barcodeVinScannerToolbar);
}
if (orientationEventListener != null) {
orientationEventListener.enable();
}
super.onResume();
}
#Override
protected void onStop() {
if (globalCamera != null) {
globalCamera.stopPreview();
cameraPreviewing = false;
globalCamera.setPreviewCallback(null);
globalCamera.release();
globalCamera = null;
}
if (orientationEventListener != null) {
orientationEventListener.disable();
}
super.onStop();
}
#Override
protected void onPause() {
if (globalCamera != null) {
globalCamera.stopPreview();
cameraPreviewing = false;
globalCamera.setPreviewCallback(null);
globalCamera.release();
globalCamera = null;
options = null;
rotationMatrix90CounterClockWise = null;
reader = null;
}
if (orientationEventListener != null) {
orientationEventListener.disable();
}
super.onPause();
}// end onPause()
//other irrelevant code was not included
}//end activity
Attempt #3, result, screen freezes , no particular error or exception reported:
Error log:
**If the eclipse GUI tool shows the desired look , than why is the toolbar still missing??? I would like to have the toolbar in the bottom , preferably using RelativeLayout without any crashes or screen freezes. Any help will be appreciated.
I'm using Samsung Galaxy S3 for testing.
Thanks.**
You wanted something like this?
the layout I used is:
<?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"
>
<LinearLayout
android:id="#+id/linearLayoutToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
>
<ImageView
android:id="#+id/imageView1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:src="#drawable/ic_launcher"
/>
<ImageView
android:id="#+id/imageView2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:src="#drawable/ic_launcher"
/>
<ImageView
android:id="#+id/imageView3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:src="#drawable/ic_launcher"
/>
</LinearLayout>
<SurfaceView
android:id="#+id/surfaceViewBarcodeScanner"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/linearLayoutToolbar"
/>
</RelativeLayout>
Please note that, since I didn't have your images in my res/drawable folder, I replaced them with ic_launcher.
Also note that I used an ldpi device running Froyo (API level 2.2). This is why the image is smaller than yours and the UI differs slighthly (...). Anyway, it works at every resolution and with every os version.
Add this to your LinearLayout containing imageView
android:layout_alignParentBottom="true"
What you really want is not to use a Relativelayout but instead use a Linearlayout as your root. Then set the surfaceview weight to 1, something like:
<SurfaceView
android:id="#+id/surfaceViewBarcodeScanner"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"/>
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/scanner_bottom_left" />
<ImageView
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/scanner_bottom_center_toolbar" />
<ImageView
android:id="#+id/imageView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/scanner_bottom_right_landscape_button" />
</LinearLayout>
You forgot to tell the surfaceView to be above the linearLayout. Your code will need to look similar to this:
<?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" >
<LinearLayout
android:id="#+id/linearLayoutToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/scanner_bottom_left" />
<ImageView
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/scanner_bottom_center_toolbar" />
<ImageView
android:id="#+id/imageView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/scanner_bottom_right_landscape_button" />
</LinearLayout>
<SurfaceView
android:id="#+id/surfaceViewBarcodeScanner"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/linearLayoutToolbar" />
</RelativeLayout>
Why do you use RelativeLayout as a root layout, I think it is much simplier to use LinearLayou with layout_weight parameter in one of children view:
<?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="match_parent">
<SurfaceView
android:layout_weight="1"
android:id="#+id/surfaceViewBarcodeScanner"
android:layout_width="match_parent"
android:layout_height="0dp" />
<!-- LinearLayout that contains toolbar that is divided into 3 sections horizontally -->
<LinearLayout
android:id="#+id/linearLayoutToolbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/scanner_bottom_left" />
<ImageView
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/scanner_bottom_center_toolbar" />
<ImageView
android:id="#+id/imageView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/scanner_bottom_right_landscape_button" />
</LinearLayout>
</LinearLayout>
try changing the layout to this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LayoutForPreview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:screenOrientation="portrait" >
<SurfaceView
android:id="#+id/surfaceViewBarcodeScanner"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_gravity="top"
android:scaleType="fitXY"
android:layout_weight="1" />
<LinearLayout
android:id="#+id/linearLayoutToolbar"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight=".1"
android:orientation="horizontal"
android:layout_gravity="bottom" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:src="#drawable/scanner_bottom_left" />
<ImageView
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.68"
android:scaleType="fitXY"
android:src="#drawable/scanner_bottom_center_toolbar" />
<ImageView
android:id="#+id/imageView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:src="#drawable/scanner_bottom_right_landscape_button" />
</LinearLayout>
I see a few mistakes in your initial XML
1. In the surfaceview you use:
android:layout_above="#+id/linearLayoutToolbar"
You should use #+id when you create an Id but when you want to make a reference you should only do #id like this:
android:layout_above="#id/linearLayoutToolbar"
2. You can't do a reference to another object that isn't created yet! So you should put the surfaceview below de linearlayout like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LayoutForPreview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:screenOrientation="portrait" >
<LinearLayout
android:id="#+id/linearLayoutToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:src="#drawable/scanner_bottom_left" />
<ImageView
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.68"
android:scaleType="fitXY"
android:src="#drawable/scanner_bottom_center_toolbar" />
<ImageView
android:id="#+id/imageView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:src="#drawable/scanner_bottom_right_landscape_button" />
</LinearLayout>
<SurfaceView
android:id="#+id/surfaceViewBarcodeScanner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#id/linearLayoutToolbar"
android:layout_gravity="top"
android:scaleType="fitXY" />
</RelativeLayout>
3. You should add weight to your 3 ImageViews like this:
android:layout_weight="1"
Some small changes in your initial layout will lead to remove the error. You need to use android:layout_height="0dp" , defining 0dp will help your surfaceview to fit in your screen.
<SurfaceView
android:id="#+id/surfaceViewBarcodeScanner"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_above="#+id/linearLayoutToolbar"
/>
And I've not found use of below attribute in SurfaceView.
android:layout_gravity="top"
android:scaleType="fitXY"
Checkout this layout designs, how android:layout_height="0dp" works, and how android:layout_width="0dp" works.
I have used that kind of layouts in many apps, and here is how should be your layout. No tricks, no praying for luck, this is just the clean, happy, and always-working way to achieve it
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:screenOrientation="portrait" >
<SurfaceView
android:id="#+id/surfaceViewBarcodeScanner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/linearLayoutToolbar"
android:layout_alignParentTop="true" />
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linearLayoutToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:src="#drawable/scanner_bottom_left" />
<ImageView
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.68"
android:scaleType="fitXY"
android:src="#drawable/scanner_bottom_center_toolbar" />
<ImageView
android:id="#+id/imageView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:src="#drawable/scanner_bottom_right_landscape_button" />
</LinearLayout>
</RelativeLayout>
here you have a preview on one of my apps.
The posted code is adapted to yours so a copy/paste will do it. please note that its everything in a simple file, so you have to change slightly your activity

Add a RelativeLayout dynamically to a LinearLayout in Android

I have been trying for a while to work out how to dynamically create a RelativeLayout with multiple views inside (e.g. TextView, ProgressBar) a LinearLayout to create a RelativeLayout beneath the previous one after every button click. Please can anyone look at my code and see if there is anything that I can do to solve this issue.
Here is the code:
activity_test_container.xml
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/frag1ScrollView"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:id="#+id/testLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".TestContainerActivity" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/testContainerTextView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/testContainerTextView1"
android:layout_marginBottom="16dp"
android:text="TextView2" />
<TextView
android:id="#+id/testContainerTextView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text="TextView1" />
<Button
android:id="#+id/testContainerButton1"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toRightOf="#+id/testContainerTextView2"
android:text="Button" />
</RelativeLayout>
</LinearLayout>
</ScrollView>
container.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/containerLayout"
android:layout_width="match_parent"
android:layout_height="80dp"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:layout_marginBottom="16dp"
android:background="#color/display_panels" >
<ProgressBar
android:id="#+id/containerProgressBar1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="#+id/containerImageButton2"
android:max="100"
android:progress="40" />
<TextView
android:id="#+id/containerTextView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/containerTextView6"
android:layout_alignLeft="#+id/containerProgressBar1"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="#+id/containerTextView6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/containerProgressBar1"
android:layout_centerHorizontal="true"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall" />
<ImageButton
android:id="#+id/containerImageButton2"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="#+id/containerTextView6"
android:background="#color/display_panels"
android:contentDescription="Okay icon"
android:src="#drawable/ic_green_ok" />
</RelativeLayout>
TestContainerActivity.java
public class TestContainerActivity extends Activity implements OnClickListener {
LinearLayout containerLayout;
Button testButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_container);
testButton = (Button)findViewById(R.id.testContainerButton1);
containerLayout = (LinearLayout)findViewById(R.id.testLayout);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.test_container, menu);
return true;
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(v==testButton){
createNewLayout();
}
}
public void createNewLayout(){
LayoutInflater layoutInflater = (LayoutInflater) getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View addView = layoutInflater.inflate(R.layout.container, null);
containerLayout.addView(addView);
}
}
I'm not entirely sure what you're problem is, but I suspect it's that the rows are not showing up at all because I don't see where you attach the listener to the Button. To handle a click event, an OnClickListener needs to be set on your View. Though this is commonly done with Buttons, OnClickListeners can be set on any view, so any size/shape widget can be made clickable. This is done with the setOnClickListener method of a View. There are multiple ways to do this, try modifying your onCreate like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_container);
testButton = (Button)findViewById(R.id.testContainerButton1);
containerLayout = (LinearLayout)findViewById(R.id.testLayout);
testButton.setOnClickListener(this);
}
An alternative method to setting your listener would be to create the listener in onCreate rather than using the Activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_container);
testButton = (Button)findViewById(R.id.testContainerButton1);
containerLayout = (LinearLayout)findViewById(R.id.testLayout);
testButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
createNewLayout();
}
});
}
In this case, you wouldn't need to have your Activity implement OnClickListener. I usually only will do something like that if I have many buttons with similar functionality, where creating listeners for each will cause a performance hit. For more isolated cases like this, I prefer to set individual Listeners since the performance difference will be negligible, but that's just my personal preference.
Hope this helps! If your problem was actually based somewhere else, please modify your question and I'll try my best to assist! Also, keep in mind that you can use the Log class to post information about execution in your LogCat output. It really helps with debugging! I suspect that if you put some logging in your listener and createNewLayout() right now, you'd see that the logging never happens because those methods are never called.

Categories

Resources