Using Google Analytics To Track Fragments - java

Just need to know the proper way to implement Google analytics to track when a user is on a fragment in real time this is what is do now
#Override
public void onResume() {
super.onResume();
Tracker myTracker = parentActivity.getTracker();
myTracker.setCustomMetric(1, (long) 1);
myTracker.sendView("Music View");
}
the getTracker class is in my main activity and just returns the instance of tracker in the main activity
Any help would be much appreciated!

Mochini's answer uses Google Analytics V2. Bellow you can see how to do it on V4 and V3:
V4:
Application:
public class YourApplication extends Application
{
public synchronized Tracker getTracker() {
try {
final GoogleAnalytics googleAnalytics = GoogleAnalytics.getInstance(this);
return googleAnalytics.newTracker(R.xml.analytics);
}catch(final Exception e){
Log.e(TAG, "Failed to initialize Google Analytics V4");
}
return null;
}
}
res/xml/analytics.xml (you can name it anything, it does not need to be called "analytics")
<?xml version="1.0" encoding="utf-8" ?>
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="TypographyDashes">
<!--Replace placeholder ID with your tracking ID-->
<string name="ga_trackingId">UA-XXXXXXXX-X</string>
<!--Enable automatic activity tracking-->
<bool name="ga_autoActivityTracking">true</bool>
<!--Disable automatic exception tracking-->
<bool name="ga_reportUncaughtExceptions">false</bool>
</resources>
build.gradle:
compile 'com.google.android.gms:play-services:7.3.0'
Fragment superclass:
public abstract class TrackedFragment extends Fragment{
#Override
public void onResume() {
super.onResume();
final Tracker tracker = yourApplicationInstance.getTracker();
if(tracker != null){
tracker.setScreenName(getClass().getSimpleName());
tracker.send(new HitBuilders.ScreenViewBuilder().build());
}
}
}
V3
import android.os.Bundle;
import android.support.v4.app.Fragment;
import com.google.analytics.tracking.android.EasyTracker;
import com.google.analytics.tracking.android.Fields;
import com.google.analytics.tracking.android.MapBuilder;
import com.google.analytics.tracking.android.Tracker;
public abstract class TrackedFragment extends Fragment{
private Tracker tracker;
#Override
public void onActivityCreated(final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
this.tracker = EasyTracker.getInstance(getActivity());
}
#Override
public void onResume() {
super.onResume();
this.tracker.set(Fields.SCREEN_NAME, getClass().getSimpleName());
this.tracker.send( MapBuilder.createAppView().build() );
}
}
Source: https://developers.google.com/analytics/devguides/collection/android/v3/migration

This an example using FragmentActivity and fragments:
Create XML file in value folder (values/analytics.xml):
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Replace placeholder ID with your tracking ID -->
<string name="ga_trackingId">XX-xxxxxxxx-x</string>
<!-- Enable Activity tracking -->
<bool name="ga_autoActivityTracking">true</bool>
<!-- Enable debug -->
<bool name="ga_debug">true</bool>
<!-- The screen names that will appear in your reporting -->
<string name="com.example.myapp.FragmentActivity">Fragment activity</string>
<!--
The inverval of time after all the collected data
should be sent to the server, in seconds.
-->
<integer name="ga_dispatchPeriod">20</integer>
</resources>
In your FragmentActivity class, add this:
#Override
protected void onStart() {
super.onStart();
EasyTracker.getInstance().setContext(this.getBaseContext());
EasyTracker.getInstance().activityStart(this); // Add this method
}
#Override
protected void onStop() {
super.onStop();
EasyTracker.getInstance().activityStop(this); // Add this method
}
Create new class in your package: TrackedFragment.java
public class TrackedFragment extends Fragment {
private Tracker tracker;
private String activityId;
private String fragmentId;
#Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EasyTracker.getInstance().setContext(getActivity().getApplicationContext());
this.tracker = EasyTracker.getTracker();
this.fragmentId = getClass().getSimpleName();
this.activityId = getActivity().getClass().getSimpleName();
}
#Override
public void onResume() {
super.onResume();
this.tracker.sendView("/" + this.activityId + "/" + this.fragmentId);
}
}
Finally, your fragment should extend from TrackedFragment like:
public class NewFragment extends TrackedFragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.newfragment, null);
}
}

Tracking methods section suggests that you just need to call EasyTracker.getInstance().setContext(getActivity()); first, then you can use the tracker in "other classes".
manual screen tracking section suggests that you can track a Fragment view with myTracker.sendView("Home Screen");

Another approach for V3 (since onResume() is tied to the Activity and not the Fragment. This works well when the parent/child relationships are well-known.
Parent Fragment sends initial event onStart():
public class ParentFragment extends Fragment {
private Tracker mTracker;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mTracker = EasyTracker.getInstance(getActivity());
}
#Override
public void onStart() {
super.onStart();
mTracker.set(Fields.SCREEN_NAME, "Parent Fragment");
mTracker.send(MapBuilder.createAppView().build());
}
}
Child Fragment overrides both onStart() and onStop() :
public class ChildFragment extends Fragment {
private Tracker mTracker;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mTracker = EasyTracker.getInstance(getActivity());
}
#Override
public void onStart() {
super.onStart();
mTracker.set(Fields.SCREEN_NAME, "Child Fragment");
mTracker.send(MapBuilder.createAppView().build());
}
#Override
public void onStop() {
super.onStop();
mTracker.set(Fields.SCREEN_NAME, "Parent Fragment");
mTracker.send(MapBuilder.createAppView().build());
}
}

Tiago's version can't be used in the new goole analytics v4. Instead, use this code from Google's docs
package com.google.android.apps.mobileplayground;
import com.google.android.apps.mobileplayground.AnalyticsSampleApp.TrackerName;
import com.google.android.gms.analytics.GoogleAnalytics;
import com.google.android.gms.analytics.HitBuilders;
import com.google.android.gms.analytics.Tracker;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
/**
* Class to exercise Event hits.
*/
public class EventFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View view = inflater.inflate(R.layout.event, container, false);
setupEvent(view, R.id.video1Play, R.string.videoCategory, R.string.videoPlay, R.string.video1);
setupEvent(view, R.id.video1Pause, R.string.videoCategory, R.string.videoPause,
R.string.video1);
setupEvent(view, R.id.video2Play, R.string.videoCategory, R.string.videoPlay, R.string.video2);
setupEvent(view, R.id.video2Pause, R.string.videoCategory, R.string.videoPause,
R.string.video2);
setupEvent(view, R.id.book1View, R.string.bookCategory, R.string.bookView, R.string.book1);
setupEvent(view, R.id.book1Share, R.string.bookCategory, R.string.bookShare, R.string.book1);
final Button dispatchButton = (Button) view.findViewById(R.id.eventDispatch);
dispatchButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// Manually start a dispatch (Unnecessary if the tracker has a dispatch interval)
GoogleAnalytics.getInstance(getActivity().getApplicationContext()).dispatchLocalHits();
}
});
return view;
}
private void setupEvent(View v, int buttonId, final int categoryId, final int actionId,
final int labelId) {
final Button pageviewButton = (Button) v.findViewById(buttonId);
pageviewButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// Get tracker.
Tracker t = ((AnalyticsSampleApp) getActivity().getApplication()).getTracker(
TrackerName.APP_TRACKER);
// Build and send an Event.
t.send(new HitBuilders.EventBuilder()
.setCategory(getString(categoryId))
.setAction(getString(actionId))
.setLabel(getString(labelId))
.build());
}
});
}
}

with android google analytics v4
i tried this and it worked
refering this https://developers.google.com/analytics/devguides/collection/android/v4/events
import java.net.URLEncoder;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Xml.Encoding;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.widget.ScrollView;
import android.widget.TextView;
import com.Blog.gkgyan.AnalyticsSampleApp.TrackerName;
import com.Blog.gkgyan.parser.RSSFeed;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdView;
import com.google.android.gms.analytics.GoogleAnalytics;
import com.google.android.gms.analytics.HitBuilders;
import com.google.android.gms.analytics.Tracker;
public class DetailFragment extends Fragment {
private int fPos;
RSSFeed fFeed;
String country;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fFeed = (RSSFeed)getArguments().getSerializable("feed");
fPos = getArguments().getInt("pos");
Tracker t = ((AnalyticsSampleApp) getActivity().getApplication()).getTracker(
TrackerName.APP_TRACKER);
// Build and send an Event.
t.send(new HitBuilders.EventBuilder()
.setCategory(fFeed.getItem(fPos).getTitle())
.setAction("viewpager click")
.setLabel("viewpager label")
.build());
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.detail_fragment, container, false);
// Initializr views
TextView title = (TextView)view.findViewById(R.id.title);
WebView desc = (WebView)view.findViewById(R.id.desc);
// Enable the vertical fading edge (by default it is disabled)
ScrollView sv = (ScrollView)view.findViewById(R.id.sv);
sv.setVerticalFadingEdgeEnabled(true);
// Set the views
desc.getSettings().setJavaScriptEnabled(true);
title.setText(fFeed.getItem(fPos).getTitle());
country = "<html xmlns=\"http://www.w3.org/1999/xhtml\"><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\"><style type=\"text/css\">p{text-align:justify;font-size:125%;}</style></head><body>" + "<p>" + fFeed.getItem(fPos).getDescription()+"</p>"+"</body></html>";
//desc.loadData( country, "text/html", "UTF-8");
//desc.loadData( country, "text/html; charset=utf-8", "utf-8");
desc.loadData( URLEncoder.encode(country).replaceAll("\\+", " "), "text/html", Encoding.UTF_8.toString());
return view;
}
}

Related

Save-Bundle with Fragments Not Saving State on Android

I have an android app that has two fragments that pass data from fragmentA to fragmentB. I can load all the data correctly but when I change the screen orientation it all reloads. I have set up the onSaveInstanceState and onViewStateRestored methods in the fragment I want to keep the state in, but nothing stays when the screen orientation changes.
The main problem that needs to be fixed is when text is loaded into the TextView in FragmentB - it needs to stay there when the screen orientation is changed.
MainActivity.Java
package com.example.tourguide;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentTransaction;
public class MainActivity extends AppCompatActivity implements FragmentA.FragmentAListener, FragmentB.FragmentBListener {
private FragmentA fragmentA;
private FragmentB fragmentB;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragmentA = new FragmentA();
fragmentB = new FragmentB();
if(savedInstanceState == null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.container_a, new FragmentA());
ft.replace(R.id.container_b, new FragmentB());
ft.commitNow();
}
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
#Override
protected void onRestoreInstanceState(#NonNull Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
#Override
public void onInputASent(CharSequence input) {
fragmentB.updateEditText(input);
}
#Override
public void onInputBSent(CharSequence input) {
fragmentA.updateEditText(input);
}
}
FragmentA.Java
package com.example.tourguide;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.ListFragment;
public class FragmentA extends ListFragment implements AdapterView.OnItemClickListener {
private FragmentAListener listener;
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String[] locationList = getActivity().getResources().getStringArray(R.array.location_list);
updateEditText(locationList[position]);
listener.onInputASent(locationList[position]);
}
public interface FragmentAListener {
void onInputASent(CharSequence input);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_a, container, false);
return v;
}
#Override
public void onListItemClick(#NonNull ListView l, #NonNull View v, int position, long id) {
super.onListItemClick(l, v, position, id);
}
public void updateEditText(CharSequence newText) {
//editText.setText(newText);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof FragmentAListener) {
listener = (FragmentAListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement FragmentAListener");
}
}
#Override
public void onDetach() {
super.onDetach();
listener = null;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ArrayAdapter arrayAdapter = ArrayAdapter.createFromResource(getActivity(), R.array.location_list, android.R.layout.simple_list_item_1);
setListAdapter(arrayAdapter);
getListView().setOnItemClickListener(this);
}
}
FragmentB.Java - This is the fragment that needs to be keep the string inside the TextView when the screen is rotated
package com.example.tourguide;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
public class FragmentB extends Fragment {
private FragmentBListener listener;
private TextView resultsFrag;
private static final String KEY_TITLE = "title_key";
private String stateObject;
public interface FragmentBListener {
void onInputBSent(CharSequence input);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_b, container, false);
resultsFrag = v.findViewById(R.id.tvFragmentB);
//I used the same if block in three different locations and none of them worked
if (savedInstanceState != null) {
String itemTo = savedInstanceState.getString(KEY_TITLE);
resultsFrag.setText(itemTo);
} else {
Toast.makeText(getActivity(), "Error 1", Toast.LENGTH_SHORT).show();
}
return v;
}
public void updateEditText(CharSequence newText) {
String newOption = newText.toString();
stateObject = newText.toString();
Resources res = getResources();
String[] locationDesc = res.getStringArray(R.array.location_description);
if (newOption.equals("Calgary")) {
resultsFrag.setText(locationDesc[0]);
} else if (newOption.equals("Victoria")) {
resultsFrag.setText(locationDesc[1]);
} else if (newOption.equals("Vancouver")) {
resultsFrag.setText(locationDesc[2]);
} else if (newOption.equals("Toronto")) {
resultsFrag.setText(locationDesc[3]);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof FragmentBListener) {
listener = (FragmentBListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement FragmentBListener");
}
}
#Override
public void onDetach() {
super.onDetach();
listener = null;
}
#Override
public void onSaveInstanceState(#NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(KEY_TITLE, resultsFrag.getText().toString());
}
#Override
public void onViewStateRestored(#Nullable Bundle savedInstanceState) {
super.onViewStateRestored(savedInstanceState);
//I used the same if block in three different locations and none of them worked
if (savedInstanceState != null) {
String itemTo = savedInstanceState.getString(KEY_TITLE);
resultsFrag.setText(itemTo);
} else {
Toast.makeText(getActivity(), "Error 2", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//I used the same if block in three different locations and none of them worked
if (savedInstanceState != null) {
String itemTo = savedInstanceState.getString(KEY_TITLE);
resultsFrag.setText(itemTo);
} else {
Toast.makeText(getActivity(), "Error 3", Toast.LENGTH_SHORT).show();
}
}
}
fragment_b.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="wrap_content"
android:background="#android:color/holo_blue_light"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="#+id/tvFragmentB"
android:layout_width="match_parent"
android:layout_height="602dp" />
</LinearLayout>
Strings
<resources>
<string name="app_name">Tour Guide</string>
<string-array name="location_list">
<item>Calgary</item>
<item>Victoria</item>
<item>Vancouver</item>
<item>Toronto</item>
</string-array>
<!-- Descriptions for the locations -->
<string-array name="location_description">
<item>This is a big description for CALGARY - THIS needs to load in for more information regarding CALGARY</item>
<item>This is a big description for VICTORIA - THIS needs to load in for more information regarding VICTORIA</item>
<item>This is a big description for VANCOUVER - THIS needs to load in for more information regarding VANCOUVER</item>
<item>This is a big description for TORONTO - THIS needs to load in for more information regarding TORONTO</item>
</string-array>
</resources>
fragment_a.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="wrap_content"
android:background="#android:color/holo_green_light"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="16dp">
<ListView
android:id="#android:id/list"
android:layout_width="wrap_content"
android:layout_height="206dp" />
</LinearLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<FrameLayout
android:id="#+id/container_a"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="#+id/container_b"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
They are saved, but you are replacing them. Use this
if(savedInstanceState == null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.container_a, new FragmentA());
ft.replace(R.id.container_b, new FragmentB());
ft.commit();
}
Please note that fragment instantiation is pretty much the ONLY scenario in which this check yields correct and expected results.
Do not keep a reference to a Fragment, unless it is obtained via findFragmentByTag + instantiation. You might want to use commitNow to get reliable results in this case.
EDIT: Update with more complete code:
public class MainActivity extends AppCompatActivity implements FragmentA.FragmentAListener, FragmentB.FragmentBListener {
private FragmentA fragmentA;
private FragmentB fragmentB;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(savedInstanceState == null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.container_a, new FragmentA(), "fragmentA");
ft.replace(R.id.container_b, new FragmentB(), "fragmentB");
ft.commitNow();
}
fragmentA = getSupportFragmentManager().findFragmentByTag("fragmentA");
fragmentB = getSupportFragmentManager().findFragmentByTag("fragmentB");
}

Animated (textView) keeps cancelling when swiping between fragments within Fragment State Adapter

I am developing an app on android studio (Java)
I have created a tabLayout that swipes between two fragments using a viewPager2 + Fragment State Adapter
On fragment02, I have animated a textView.
When I swipe onto the fragment the animation plays on loop, as it should.
However, if I swipe off the fragment and then back on, the animation is no longer playing.
I really need the animation to continue.
Any advice is welcome and I thank you in advance :)
Please be aware I am rather new to this.
// MainActivity.java
package Zoomie.App;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;
import android.os.Bundle;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportActionBar().setTitle("Welcome");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
ViewPager2 viewPager2 = findViewById(R.id.ViewPager);
viewPager2.setAdapter(new FragmentPagerAdapter(this));
TabLayout tabLayout = findViewById(R.id.tabLayout);
TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(
tabLayout, viewPager2, new TabLayoutMediator.TabConfigurationStrategy() {
#Override
public void onConfigureTab(#NonNull TabLayout.Tab tab, int position) {
switch (position) {
case 0: {
tab.setText("Fragment 01");
break;
}
default: {
tab.setText("Fragment 02");
break;
}
}
}
});
tabLayoutMediator.attach();
}
}
// FragmentPagerAdapter.java
package Zoomie.App;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;
public class FragmentPagerAdapter extends FragmentStateAdapter {
public FragmentPagerAdapter(#NonNull FragmentActivity fragmentActivity) {
super(fragmentActivity);
}
#NonNull
#Override
public Fragment createFragment(int position) {
switch (position){
case 0:
return new Fragment01();
default:
return new Fragment02();
}
}
#Override
public int getItemCount() {
return 2;
}
}
// Fragment02.java
package Zoomie.App;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.TextView;
public class Fragment02 extends Fragment {
public Fragment02() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView=inflater.inflate(R.layout.fragment_02, container, false);
TextView fade01 = (TextView) rootView.findViewById(R.id.textView_fade_01);
Animation fade = AnimationUtils.loadAnimation(getActivity(), R.anim.fade_animation);
fade01.startAnimation(fade);
return rootView;
}
}
// fade_animation.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:fromAlpha="0"
android:toAlpha=".5"
android:duration="375"
android:repeatMode="reverse"
android:repeatCount="infinite"
/>
</set>
You should move the loading animation method into onResume() lifecycle method. In your case:
private TextView fade01;
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState
) {
View rootView = inflater.inflate(R.layout.fragment_02, container, false);
fade01 = (TextView) rootView.findViewById(R.id.textView_fade_01);
return rootView;
}
#Override
public void onResume() {
super.onResume();
Animation fade = AnimationUtils.loadAnimation(getActivity(), R.anim.fade_animation);
fade01.startAnimation(fade);
}

ZXingScannerView in another class than Main

I want to create a QR scan code system using ZXingScannerView, but i want to use this interface not in base class. I decided to create a xml file when I have just ZXingScannerView and I call functions on this, but it's not working.
This is my class when I run my Code Scanner by button click:
package com.example.elistazakupow3;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import Models.ShoppingList;
public class FragmentShoppingList extends Fragment {
protected View view;
private RecyclerView myRecyclerView;
private ArrayList<ShoppingList> lstShoppingList;
Button scan_button;
#Nullable
#Override
public View onCreateView(#NonNull final LayoutInflater inflater, #Nullable final ViewGroup container, #Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_shopping_list, container,false);
myRecyclerView = view.findViewById(R.id.myRC);
myRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
MyRecyclerViewAdapter recyclerViewAdapter = new MyRecyclerViewAdapter(lstShoppingList);
myRecyclerView.setAdapter(recyclerViewAdapter);
//Scanner
scan_button = view.findViewById(R.id.scan_button);
scan_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new CodeScanner();
}
});
return view;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState){
super.onCreate(savedInstanceState);
lstShoppingList = new ArrayList<>();
lstShoppingList.add(new ShoppingList("Na wigiliÄ™","Nie wiem","23.04.1998"));
}
}
And my CodeScanner class
package com.example.elistazakupow3;
import android.app.AlertDialog;
import com.google.zxing.Result;
import me.dm7.barcodescanner.zxing.ZXingScannerView;
public class CodeScanner extends FragmentShoppingList implements ZXingScannerView.ResultHandler {
private ZXingScannerView mScannerView;
public CodeScanner(){
mScannerView = getActivity().findViewById(R.id.scaner);
mScannerView.setResultHandler(this);
mScannerView.startCamera();
}
#Override
public void onPause(){
super.onPause();
mScannerView.stopCamera();
}
#Override
public void handleResult(Result result) {
// Toast.makeText(getContext(), "Contents = " + result.getText() + ", Format = " + result.getBarcodeFormat().toString(), Toast.LENGTH_SHORT).show();
AlertDialog.Builder bd = new AlertDialog.Builder(getActivity());
bd.setTitle("Wynik skanowania");
bd.setMessage(result.getText());
AlertDialog pokazKod = bd.create();
pokazKod.show();
}
}
You can't show a Fragment in that manner. Read this and try to follow it in your code.
Move this to onResume:
mScannerView.setResultHandler(this);
mScannerView.startCamera();
You're supposed to create a new ZXingScannerView and return it in your CodeScanner's onCreateView, the idea is that instead of inflating an XML, you're instantiating ZXingScannerView as your whole UI. Instead of mScannerView = getActivity().findViewById(R.id.scaner);, do something like this in your CodeScanner fragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mScannerView= new ZXingScannerView(requireContext());
return mScannerView;
}

Activity missing in manifest when declair

There is two arrows as you see in picture ..
one indicate to Activities in my project
other one indicate to recommended activity to declare in manifest ..
but there is no recommended activity except " StreamingActivity "
when i run my application ,, application show me that message " Unfortunately , application has stopped "
this code for publisheractivity
package khaabbas.huthaifa.com.talk_listen;
import android.hardware.Camera;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import com.red5pro.streaming.R5Connection;
import com.red5pro.streaming.R5Stream;
import com.red5pro.streaming.R5StreamProtocol;
import com.red5pro.streaming.config.R5Configuration;
import com.red5pro.streaming.source.R5Camera;
import com.red5pro.streaming.source.R5Microphone;
//import android.graphics.Camera;
public class PublishFragment extends android.support.v4.app.Fragment implements SurfaceHolder.Callback {
public static android.support.v4.app.Fragment newInstance() {
PublishFragment fragment = new PublishFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
public PublishFragment() {
// Required empty public constructor
}
public R5Configuration configuration;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
configuration = new R5Configuration(R5StreamProtocol.RTSP, "localhost", 8554, "live", 1.0f);
configuration.setLicenseKey("NBZF-UFM2-GCEP-OUYZ");
configuration.setBundleID(getActivity().getPackageName());
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_publish, container, false);
return v;
}
protected Camera camera;
protected boolean isPublishing = false;
protected R5Stream stream;
private void preview() {
camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
SurfaceView surface = (SurfaceView) getActivity().findViewById(R.id.surfaceView);
surface.getHolder().addCallback(this);
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
}
catch(Exception e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) {
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
}
#Override
public void onResume() {
super.onResume();
preview();
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Button publishButton = (Button) getActivity().findViewById(R.id.publishButton);
publishButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onPublishToggle();
}
});
}
private void onPublishToggle() {
Button publishButton = (Button) getActivity().findViewById(R.id.publishButton);
if(isPublishing) {
stop();
}
else {
start();
}
isPublishing = !isPublishing;
publishButton.setText(isPublishing ? "stop" : "start");
}
public void start() {
camera.stopPreview();
stream = new R5Stream(new R5Connection(configuration));
stream.setView((SurfaceView) getActivity().findViewById(R.id.surfaceView));
R5Camera r5Camera = new R5Camera(camera, 320, 240);
R5Microphone r5Microphone = new R5Microphone();
stream.attachCamera(r5Camera);
stream.attachMic(r5Microphone);
stream.publish("red5prostream", R5Stream.RecordType.Live);
camera.startPreview();
}
public void stop() {
if(stream != null) {
stream.stop();
camera.startPreview();
}
}
#Override
public void onPause() {
super.onPause();
if(isPublishing) {
onPublishToggle();
}
}
}
Remove both this activity because u used only single activity it define activity and two other is fragment.
<activity android:name=".S"/>
<activity android:name=".Sub"/>
and fragment call used below code..
Fragment fragment = new HomeFragment();
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_frame, fragment, fragment.getClass().getSimpleName()).addToBackStack(null).commit();
No need to declare fragment on manifest, remove fragment declaration from manifest because you are declare fragment within section in manifest file.

ActionBarSherlock and FragmentTabsPager

As a lot of people have been doing so far, I'm implementing the FragmentTabsPager into my app, which is using ActionBarSherlock 4.0. However, I'm lost.
Fragments, and all of Google's little ideas, plans and methods surrounding it, are confusing me. If anyone could take a look at my code and walk me through this, providing help in making it work, I would thank them a thousand times :D.
I have another project with a sort-of beginning for a ViewPager, but the Tabs just mix better, especially with them being in the ActionBar on landscape and tablets.
My code is all zipped up and ready to go over here:
http://dl.dropbox.com/u/21807195/Antonius%20College%202.zip
Thanks in advance!
I will show you my code that has a ViewPager, TabListener, and system of Fragments linked to each tab. It implements ABS, but as of yet, still crashes on Gingerbread and lower (works beautifully on ICS, though):
import java.util.ArrayList;
import library.DatabaseHandler;
import org.json.JSONObject;
import com.actionbarsherlock.R;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.ActionBar.Tab;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View.OnClickListener;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
public class Polling extends SherlockFragmentActivity {
private ViewPager mViewPager;
private TabsAdapter mTabsAdapter;
private final static String TAG = "21st Polling:";
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mViewPager = new ViewPager(this);
mViewPager.setId(R.id.pager);
setContentView(mViewPager);
ActionBar bar = getSupportActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayShowTitleEnabled(false);
bar.setDisplayShowHomeEnabled(false);
mTabsAdapter = new TabsAdapter(this, mViewPager);
mTabsAdapter.addTab(bar.newTab().setText(R.string.login),
LoginFragment.class, null);
mTabsAdapter.addTab(bar.newTab().setText(R.string.economics),
EconFragment.class, null);
mTabsAdapter.addTab(bar.newTab().setText(R.string.elections),
ElectionsFragment.class, null);
mTabsAdapter.addTab(bar.newTab().setText(R.string.politics),
PoliticsFragment.class, null);
mTabsAdapter.addTab(bar.newTab().setText(R.string.science),
ScienceFragment.class, null);
mTabsAdapter.addTab(bar.newTab().setText(R.string.finance),
FinanceFragment.class, null);
mTabsAdapter.addTab(bar.newTab().setText(R.string.religion),
ReligionFragment.class, null);
mTabsAdapter.addTab(bar.newTab().setText(R.string.military),
MilitaryFragment.class, null);
mTabsAdapter.addTab(bar.newTab().setText(R.string.international),
InternationalFragment.class, null);
Log.v(TAG, (String)bar.getTabAt(0).getText());
}
public static class TabsAdapter extends FragmentPagerAdapter
implements ActionBar.TabListener, ViewPager.OnPageChangeListener {
private final Context mContext;
private final ActionBar mActionBar;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
static final class TabInfo {
private final Class<?> clss;
private final Bundle args;
TabInfo(Class<?> _class, Bundle _args) {
clss = _class;
args = _args;
}
}
public TabsAdapter(SherlockFragmentActivity activity, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mActionBar = activity.getSupportActionBar();
mViewPager = pager;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
TabInfo info = new TabInfo(clss, args);
tab.setTag(info);
tab.setTabListener(this);
mTabs.add(info);
mActionBar.addTab(tab);
notifyDataSetChanged();
}
public int getCount() {
return mTabs.size();
}
public SherlockFragment getItem(int position) {
TabInfo info = mTabs.get(position);
return (SherlockFragment)Fragment.instantiate(mContext, info.clss.getName(), info.args);
}
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
public void onPageSelected(int position) {
mActionBar.setSelectedNavigationItem(position);
}
public void onPageScrollStateChanged(int state) {
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
mViewPager.setCurrentItem(tab.getPosition());
//Log.v(TAG, "clicked");
Object tag = tab.getTag();
for (int i=0; i<mTabs.size(); i++) {
if (mTabs.get(i) == tag) {
mViewPager.setCurrentItem(i);
}
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {}
public void onTabReselected(Tab tab, FragmentTransaction ft) {}
public void onTabReselected(Tab tab, android.app.FragmentTransaction ft) {}
public void onTabUnselected(Tab tab, android.app.FragmentTransaction ft) {}
}
And here is what one fragment looks like:
package com.davekelley.polling;
import com.actionbarsherlock.R;
import com.actionbarsherlock.app.SherlockFragment;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class MilitaryFragment extends SherlockFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.militaryfragment, container, false);
}
}
My last note would that my code still has one other issue: individual fragments do not always reload their interface after the user press back (which results in removing the entire app from the screen, regardless which tab/fragment they are on, because I have no backStack). So that's what I'm working through now. I think once I have that sorted, I'll try to figure out why I still don't have Gingerbread execution functioning properly. Either way, I hope looking through this code helps you out.
Here is a fragment with some onClickListeners:
import com.actionbarsherlock.R;
import com.actionbarsherlock.app.SherlockFragment;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;
public class LoginFragment extends SherlockFragment {
Button loginButton;
Button registerButton;
Polling activity;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.loginfragment, container, false);
return v;
}
public void onResume() {
super.onResume();
Log.d("Econ", "onresume");
loginButton = (Button) getActivity().findViewById(R.id.loginButton);
loginButton.setOnClickListener(loginListener);
registerButton = (Button) getActivity().findViewById(R.id.registerButton);
registerButton.setOnClickListener(registerListener);
}
public OnClickListener loginListener = new OnClickListener() {
#Override
public void onClick(View v) {
if(loginButton.getText().toString() == "Log Out") {
activity.loginReport(2);
loginButton.setText(R.string.login);
//Remove user from dB sqllite when I know how
}
else {
Log.v("LoginF", "onclick");
ProgressDialog progressDialog = new ProgressDialog(getActivity());
progressDialog.setMessage("Logging in...");
LoginTask loginTask = new LoginTask((Polling) getActivity(), progressDialog);
loginTask.execute();
}
}
};
public OnClickListener registerListener = new OnClickListener() {
#Override
public void onClick(View v) {
Log.v("Register", "onclick");
ProgressDialog progressDialog = new ProgressDialog(getActivity());
progressDialog.setMessage("Registering new user...");
RegisterTask registerTask = new RegisterTask((Polling) getActivity(), progressDialog);
registerTask.execute();
}
};
public void onAttach(Activity activity) {
super.onAttach(activity);
this.activity = (Polling) activity;
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
public void onStart() {
super.onStart();
Log.d("Econ", "onstart");
}
public void onPause() {
super.onPause();Log.d("Econ", "onpause");
}
public void onStop() {
super.onStop();
Log.d("Econ", "onstop");
}
public void onDestroyView() {
super.onDestroyView();
Log.d("Econ", "ondestroyview");
}
public void onDestroy() {
super.onDestroy();
Log.d("Econ", "ondestroy");
}
public void onDetach() {
super.onDetach();
Log.d("Econ", "ondetach");
}
}
The loginTask objects that you see are actually classes that extend ASyncTask - they handle connecting to my server and registering/logging in.
I thought it would be helpful to add in one bit more of code. This is another one of my fragments, like LoginFragment, but it inflates a UI a little differently. Eventually, what you see in the while loop below, will head into an ASyncTask to acquire each question from the server, rather than the dummy string array you see:
public class EconFragment extends SherlockFragment {
private TableLayout questionContainer;
int pos = 0;
private String[] titles = {"The first title ", "hallo1","hallo2", "hallo3",
"hallo4", "hallo5","hallo6", "hallo7","hallo8", "hallo9"};
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.v("Econ", "onCreateView");
View v = inflater.inflate(R.layout.econfragment, container, false);
questionContainer = (TableLayout) v.findViewById(R.id.questionContainer);
//bs
int leftMargin=5;
int topMargin=5;
int rightMargin=5;
int bottomMargin=5;
while (pos < 10) {
View question = inflater.inflate(R.layout.question, null);
question.setId(pos);
TextView title = (TextView) question.findViewById(R.id.questionTextView);
title.setText(titles[pos]);
Button charts = (Button) question.findViewById(R.id.chartsButton);
charts.setId(pos);
charts.setOnClickListener(chartsListener);
TableRow tr = (TableRow) question;
TableLayout.LayoutParams trParams = new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT);
trParams.setMargins(leftMargin, topMargin, rightMargin, bottomMargin);
tr.setLayoutParams(trParams);
Log.v("econ", "while loop");
questionContainer.addView(tr);
pos++;
}
pos = 0;
return v;
}
I have ported the FragmentTabsPager Activity and associated Fragments from "Support4Demos" (Android Support library sample) to use ActionBarSherlock and true ActionBar Tabs. The sample includes an Activity that uses both a ViewPager and Tabs to switch between Fragments. The Fragments contain three kinds of ListViews. I've tested it from ICS down to Eclair (2.1). You can browse or download the code at http://code.google.com/p/sherlock-demo/.

Categories

Resources