Dependency reference: journeyapps/zxing-android-embedded
Description of the problem:
I'm new to Android Data binding & cannot bind the resource id zxing_viewfinder_view which is inside <merge> </merge>
Here is my code for understanding.
activity_scan_qr.xml
<LinearLayout
android:id="#+id/ll_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_below="#+id/ll_header"
android:background="#color/color_white"
android:gravity="center"
android:orientation="vertical">
<com.journeyapps.barcodescanner.DecoratedBarcodeView
android:id="#+id/zxing_barcode_scanner"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:zxing_scanner_layout="#layout/view_custom_qr_scanner"/>
</LinearLayout>
view_custom_qr_scanner.xml
<?xml version="1.0" encoding="utf-8"?>
<merge 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">
<com.journeyapps.barcodescanner.BarcodeView
android:id="#+id/zxing_barcode_surface"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:zxing_framing_rect_height="250dp"
app:zxing_framing_rect_width="250dp" />
<com.journeyapps.barcodescanner.ViewfinderView
android:id="#+id/zxing_viewfinder_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:zxing_possible_result_points="#color/zxing_custom_possible_result_points"
app:zxing_result_view="#color/zxing_custom_result_view"
app:zxing_viewfinder_laser="#color/zxing_custom_viewfinder_laser"
app:zxing_viewfinder_laser_visibility="true"
app:zxing_viewfinder_mask="#color/zxing_custom_viewfinder_mask" />
<TextView
android:id="#+id/zxing_status_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:background="#color/zxing_transparent"
android:text="Place a QR code inside the scan area."
android:textColor="#color/zxing_status_text" />
</merge>
ScanQRActivity.java
public class ScanQRActivity extends AppCompatActivity implements DecoratedBarcodeView.TorchListener {
public static final String TAG = ScanQRActivity.class.getSimpleName();
Context mContext;
Activity mActivity;
ActivityScanQrBinding binding;
ActionBar actionBar;
private CaptureManager capture;
boolean bFlashLight = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityScanQrBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
mContext = this;
mActivity = this;
capture = new CaptureManager(this, binding.zxingBarcodeScanner);
capture.initializeFromIntent(getIntent(), savedInstanceState);
capture.setShowMissingCameraPermissionDialog(true);
capture.decode();
changeLaserVisibility(true);
}
public void changeLaserVisibility(boolean visible) {
binding.zxingViewfinderView.setLaserVisibility(visible);
}
}
To use data binding you need to place your layout inside tag.
Your activity.xml
<layout>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/ll_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_below="#+id/ll_header"
android:background="#color/color_white"
android:gravity="center"
android:orientation="vertical">
<com.journeyapps.barcodescanner.DecoratedBarcodeView
android:id="#+id/zxing_barcode_scanner"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:zxing_scanner_layout="#layout/view_custom_qr_scanner"/>
</LinearLayout>
</layout>
Your view_custom_qr_scanner.xml file should be
<layout>
<merge 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">
<com.journeyapps.barcodescanner.BarcodeView
android:id="#+id/zxing_barcode_surface"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:zxing_framing_rect_height="250dp"
app:zxing_framing_rect_width="250dp" />
<com.journeyapps.barcodescanner.ViewfinderView
android:id="#+id/zxing_viewfinder_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:zxing_possible_result_points="#color/zxing_custom_possible_result_points"
app:zxing_result_view="#color/zxing_custom_result_view"
app:zxing_viewfinder_laser="#color/zxing_custom_viewfinder_laser"
app:zxing_viewfinder_laser_visibility="true"
app:zxing_viewfinder_mask="#color/zxing_custom_viewfinder_mask" />
<TextView
android:id="#+id/zxing_status_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:background="#color/zxing_transparent"
android:text="Place a QR code inside the scan area."
android:textColor="#color/zxing_status_text" />
</merge>
</layout>
In your activity, create a new variable of type 'binding' that would be
private ViewCustomQrScannerBinding bindingCustomScanner
, now in your "OnCreate" under "binding = ActivityScanQrBinding.inflate (getLayoutInflater ());"
add this line
bindingCustomScanner = ViewCustomQrScannerBinding.bind (binding.root)
now when you call the properties of the new view, you call the new 'bindingCustomScanner'
Related
The Error:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.databinding.ViewDataBinding.executePendingBindings()' on a null object reference
I double checked the names to the references used. Seems fine to me. I don't know why I keep getting this error. The view crashes as soon as I open it.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_findfriend);
searcher = Searcher.create(ALGOLIA_APP_ID, ALGOLIA_SEARCH_API_KEY, ALGOLIA_INDEX_NAME);
helper = new InstantSearch(this, searcher);
helper.search();
// Get a reference to your Hits widget
final Hits hits = (Hits) findViewById(R.id.hits);
// Add an OnItemClickListener
hits.setOnItemClickListener(new ItemClickSupport.OnItemClickListener() {
#Override
public void onItemClick(RecyclerView recyclerView, int position, View v) {
JSONObject hit = hits.get(position);
// Do something with the hit
}
});
}
#Override
protected void onDestroy() {
searcher.destroy();
super.onDestroy();
}
}
Here's my Activity:
activity_findfriend.xml
<?xml version="1.0" encoding="utf-8"?>
<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"
xmlns:algolia="http://schemas.android.com/apk/res-auto"
android:paddingTop="0dp"
android:background="#color/white">
<LinearLayout
android:id="#+id/search_emoji"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="0dp"
android:layout_marginTop="0dp"
android:background="#drawable/search_drawable"
android:gravity="top"
android:paddingTop="8dp"
android:orientation="horizontal">
<com.algolia.instantsearch.ui.views.SearchBox
android:id="#+id/searchBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/message_rectangle"
android:layout_marginRight="12dp"
android:layout_marginLeft="12dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/search_emoji">
<com.algolia.instantsearch.ui.views.Hits
android:id="#+id/hits"
android:layout_width="match_parent"
android:layout_height="wrap_content"
algolia:itemLayout="#layout/hits_item"
android:layout_below="#+id/search_emoji"/>
</LinearLayout>
To use data binding in your layout, wrap it in a <layout> root tag.
New hits_item.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:algolia="http://schemas.android.com/apk/res-auto">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:focusable="true"
android:id="#+id/hits_items">
<de.hdodenhof.circleimageview.CircleImageView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/user_image"
android:layout_width="100dp"
android:layout_height="100dp"
app:civ_border_width="4dp"
android:layout_marginStart="8dp"
android:layout_marginTop="20dp"
android:src="#drawable/profile_thumbnail"
app:civ_border_color="#c42f92"
algolia:attribute='#{"image"}'/>
<TextView
android:id="#+id/user_name"
android:paddingTop="53dp"
android:paddingLeft="20dp"
android:textSize="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
algolia:attribute='#{"username"}'
algolia:highlighted='#{true}'/>
</LinearLayout>
</layout>
I am stuck at this point where I am adding a Fragment in a NavigationDrawer activity. When the activity displays the fragment, the fragment bumps up the whole screen as shown in the image below:
The expected behaviour is as shown in the image below.
I am using databinding with a RecyclerView. StockListItem is the POJO class used for accessing data in RecyclerView and stock_list_item_layout is the layout used for displaying list items in RecylerView.
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
private RecyclerViewAdapter adapter;
DrawerLayout drawer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open,
R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView)
findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
getSupportFragmentManager().beginTransaction().add(R.id.flContainer,new
WatchlistFragment()).commit();
}
}
public class WatchlistFragment extends Fragment {
private FragmentWatchlistBinding watchlistBinding;
private RecyclerViewAdapter adapter;
private List<StockListItem> lstStockItems = new ArrayList<>();
public WatchlistFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_watchlist, container,
false);
Toast.makeText(getActivity(), "Reached WatchlistFragment.",
Toast.LENGTH_SHORT).show();
watchlistBinding =
DataBindingUtil.setContentView(getActivity(),R.layout.fragment_watchlist);
watchlistBinding.rvMyRecyclerView.setLayoutManager(new
LinearLayoutManager(getActivity()));
watchlistBinding.rvMyRecyclerView.setHasFixedSize(false);
lstStockItems.add(new StockListItem("Vedanta
Ltd","174.45","+5.35","+3.45"));
lstStockItems.add(new StockListItem("Eicher Motors
Ltd","19974.45","+545.35","+13.45"));
lstStockItems.add(new StockListItem("Adani Green Energy
Ltd","34.45","+5.35","+3.45"));
lstStockItems.add(new StockListItem("Federal Bank
Ltd","84.45","+5.35","+3.45"));
lstStockItems.add(new StockListItem("Hindustan Zinc
Ltd","274.45","+5.35","+3.45"));
lstStockItems.add(new StockListItem("Indian Oil Corporation
Ltd","154.45","+5.35","+3.45"));
lstStockItems.add(new StockListItem("Hindustan Petroleum Corporation
Ltd","154.45","+5.35","+3.45"));
lstStockItems.add(new StockListItem("ITC
Ltd","274.45","+5.35","+3.45"));
adapter = new RecyclerViewAdapter(getActivity(),lstStockItems);
watchlistBinding.rvMyRecyclerView.setAdapter(adapter);
return v;
}}
This is what my fragment_watchlist.xml looks like.
<?xml version="1.0" encoding="utf-8"?>
<layout >
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".WatchlistFragment"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content">
<TextView
android:text="Watchlist"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.v7.widget.RecyclerView
android:id="#+id/rvMyRecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</FrameLayout>
</layout>
public class RecyclerViewAdapter extends
RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder> {
private Context ctx;
private List<StockListItem> lstUsers = new ArrayList<>();
public RecyclerViewAdapter(Context ctx, List<StockListItem> lstUsers) {
this.ctx = ctx;
this.lstUsers = lstUsers;
}
#NonNull
#Override
public RecyclerViewAdapter.MyViewHolder onCreateViewHolder(#NonNull
ViewGroup viewGroup, int i) {
StockListItemLayoutBinding stockListItemLayoutBinding =
DataBindingUtil.inflate(LayoutInflater.from(viewGroup.getContext()),
R.layout.stock_list_item_layout,viewGroup,false);
MyViewHolder myViewHolder = new
MyViewHolder(stockListItemLayoutBinding);
return myViewHolder;
}
#Override
public void onBindViewHolder(#NonNull RecyclerViewAdapter.MyViewHolder
viewHolder, int i) {
StockListItem stockListItem = lstUsers.get(i);
viewHolder.stockListItemLayoutBinding.setStock(stockListItem);
}
#Override
public int getItemCount() {
return lstUsers.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder
{
StockListItemLayoutBinding stockListItemLayoutBinding;
public MyViewHolder(#NonNull StockListItemLayoutBinding
stockListItemLayoutBinding) {
super(stockListItemLayoutBinding.getRoot());
this.stockListItemLayoutBinding = stockListItemLayoutBinding;
}
}
}
public class StockListItem
{
private String StockName;
private String StockPrice;
private String StockPriceChange;
private String StockPriceChangePercent;
public String getStockPriceChange() {
return StockPriceChange;
}
public String getStockPriceChangePercent() {
return StockPriceChangePercent;
}
public void setStockPriceChange(String stockPriceChange) {
StockPriceChange = stockPriceChange;
}
public void setStockPriceChangePercent(String stockPriceChangePercent) {
StockPriceChangePercent = stockPriceChangePercent;
}
public void setStockName(String stockName) {
StockName = stockName;
}
public void setStockPrice(String stockPrice) {
StockPrice = stockPrice;
}
public String getStockName() {
return StockName;
}
public String getStockPrice() {
return StockPrice;
}
public StockListItem(String stockName, String stockPrice, String
stockPriceChange, String stockPriceChangePercent) {
this.StockName = stockName;
this.StockPrice = stockPrice;
this.StockPriceChange = stockPriceChange;
this.StockPriceChangePercent = stockPriceChangePercent;
}
}
This is what stock_list_item_layout.xml looks like.
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
type="com.example.mvp1stockmeter.StockListItem"
name="Stock"/>
</data>
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:foreground="?attr/selectableItemBackground"
android:layout_margin="4dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/tvStockName"
android:layout_margin="16dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{Stock.StockName}"
android:layout_alignParentLeft="true"/>
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:gravity="right">
<TextView
android:id="#+id/tvStockPrice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:text="#{Stock.StockPrice}"
android:textSize="20sp"
/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="#+id/tvStockPriceChange"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:text="#{Stock.StockPriceChange}"
android:textSize="16sp"
android:layout_alignParentRight="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:text="("
android:textSize="16sp"/>
<TextView
android:id="#+id/tvStockPriceChangePercent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:text="#{Stock.StockPriceChangePercent}"
android:textSize="16sp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:text="%)"
android:textSize="16sp" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
</android.support.v7.widget.CardView>
</layout>
This is what my activity_main.xml looks like. -
<?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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".MainActivity"
tools:showIn="#layout/app_bar_main"
android:orientation="vertical">
<FrameLayout
android:visibility="visible"
android:id="#+id/flContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</FrameLayout>
</LinearLayout>
app_bar_main.xml layout file looks like-
<android.support.design.widget.CoordinatorLayout
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"
tools:context=".MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_main" />
</android.support.design.widget.CoordinatorLayout>
The content_main.xml file looks like this-
<?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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".MainActivity"
tools:showIn="#layout/app_bar_main"
android:orientation="vertical">
<FrameLayout
android:visibility="visible"
android:id="#+id/flContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="?attr/actionBarSize">
</FrameLayout>
</LinearLayout>
This is how my nav_header_main.xml file looks like-
<?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"
android:layout_width="match_parent"
android:layout_height="#dimen/nav_header_height"
android:background="#drawable/side_nav_bar"
android:gravity="bottom"
android:orientation="vertical"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
android:theme="#style/ThemeOverlay.AppCompat.Dark">
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="#string/app_name"
android:paddingTop="#dimen/nav_header_vertical_spacing"
app:srcCompat="#mipmap/ic_launcher_round" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="#dimen/nav_header_vertical_spacing"
android:text="#string/app_name"
android:textAppearance="#style/TextAppearance.AppCompat.Body1" />
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/website" />
</LinearLayout>
This is how my activity_main_drawer.xm file looks like-
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:showIn="navigation_view">
<group android:checkableBehavior="single">
<item
android:id="#+id/nav_watchlist"
android:icon="#drawable/ic_menu_camera"
android:title="Watchlist" />
<item
android:id="#+id/nav_profile"
android:icon="#drawable/ic_menu_manage"
android:title="Profile" />
<item
android:id="#+id/nav_suggestions_or_complaints"
android:icon="#drawable/ic_menu_manage"
android:title="Suggestions / Complaints" />
<item
android:id="#+id/nav_upcoming_features"
android:icon="#drawable/ic_menu_manage"
android:title="Upcoming Features" />
</group>
</menu>
This is how my main.xml file looks like -
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_settings"
android:orderInCategory="100"
android:title="#string/action_settings"
app:showAsAction="never" />
</menu>
Just add android:layout_marginTop="?attr/actionBarSize" in your activity_main's FrameLayout, like this:
<FrameLayout
android:visibility="visible"
android:layout_marginTop="?attr/actionBarSize"
android:id="#+id/flContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</FrameLayout>
I have a MainActivity that contains a NavigationView for the drawer menu. The NavigationView's header contains a TextView that I want to populate with some user information.
The problem is, that sometimes the app crashes in the onChanged method with a NullPointerException because textUsername is null. My guess is that's because the layout has not been fully inflated yet. I have implemented the null check (as seen in the code below), which obviously just results in the textUsername being blank in most cases.
My onCreate method looks like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainViewModel = ViewModelProviders.of(this).get(MainViewModel.class);
mainDrawerLayout = (DrawerLayout) findViewById(R.id.main_drawer_layout);
mainNavigationView = (NavigationView) findViewById(R.id.main_navigation_view);
mainContentLayout = (CoordinatorLayout) findViewById(R.id.main_content_layout);
// get user information
NetworkController.getInstance().getCurrentUser(Utils.getAuthenticationToken(), new NetworkController.GetUserResponseCallback() {
#Override
public void onGetUser(Response<UserResponse> response) {
if(response.isSuccessful() && response.body() != null && response.body().isSuccess()) {
mainViewModel.setCurrentUser(response.body().getUser());
}
}
#Override
public void onRequestFailed(Throwable throwable) {
}
});
mainViewModel.getCurrentUser().observe(this, new Observer<User>() {
#Override
public void onChanged(#Nullable User user) {
TextView textUsername = (TextView) mainNavigationView.findViewById(R.id.drawer_header_username);
if(textUsername != null) {
textUsername.setText(user.getProfile().getUsername());
}
}
});
}
How can I make sure that that layout is inflated before I access it from the callback? Thanks.
EDIT
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
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:fitsSystemWindows="true"
tools:openDrawer="start"
android:id="#+id/main_drawer_layout">
<include
layout="#layout/activity_main_content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/main_navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/drawer_menu_header"
app:menu="#menu/main_drawer_menu">
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
activity_main_content.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/main_content_layout">
<!-- setup the toolbar -->
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/main_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="#dimen/toolbar_elevation"
android:popupTheme="#style/AppTheme.PopupOverlay">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<!-- include the fragment container -->
<android.support.constraint.ConstraintLayout
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:activity="com.fishley.android.activities.MainActivity"
android:id="#+id/main_fragment_container"
android:paddingTop="?attr/actionBarSize">
</android.support.constraint.ConstraintLayout>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab_new_post"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
android:src="#drawable/ic_plus"
android:tint="#android:color/white"
android:visibility="gone"/>
</android.support.design.widget.CoordinatorLayout>
drawer_menu_header.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"
android:layout_width="match_parent"
android:layout_height="#dimen/nav_header_height"
android:gravity="bottom"
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"
android:theme="#style/ThemeOverlay.AppCompat.Dark"
android:background="#drawable/drawer_menu_header_background">
<TextView
android:id="#+id/drawer_header_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="#dimen/nav_header_vertical_spacing"
android:text="Android Studio"
android:textColor="#android:color/black"
android:textAppearance="#style/TextAppearance.AppCompat.Body1"/>
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#android:color/black"
android:text="android.studio#android.com"/>
</LinearLayout>
Here is my layout for Activity. And I want to display android.widget.ProgressBar in the middle of the screen dynamically.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.CoordinatorLayout
android:id="#+id/myCoordinator"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<include layout="#layout/toolbar" />
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/frameContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<RelativeLayout
android:id="#+id/rlSearchToolContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#color/colorPrimary"
android:gravity="bottom"
android:layout_gravity="bottom"
android:visibility="gone">
<LinearLayout
android:id="#+id/llSearchComponentContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#color/colorPrimary"
android:layout_toLeftOf="#+id/btnDone"
android:gravity="bottom"
android:orientation="horizontal"></LinearLayout>
<Button
android:id="#+id/btnDone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="Done"/>
</RelativeLayout>
</android.support.design.widget.CoordinatorLayout>
<FrameLayout
android:id="#+id/frameLeftSlide"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start" />
</android.support.v4.widget.DrawerLayout>
Now In that FrameLayout (id = frameContainer) I replace a Fragment that is BaseFragment.(fragment_base.xml)
MainActivity.java
class MainActivity extends AppCompatActivity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BaseFragment mFileListFragment = new BaseFragment();
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.frameContainer, mFileListFragment);
transaction.commit();
}
}
fragment_base.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="vertical">
<FrameLayout
android:id="#+id/frameContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"/>
</LinearLayout>
BaseFragment.java
public class BaseFragment extends Fragment{
private View mView;
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
if (mView == null) {
mView = inflater.inflate(R.layout.fragment_phone_file_base, null);
setLayoutViews(mView);
}
return mView;
}
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
FileListFragment mFileListFragment = new FileListFragment();
FragmentManager manager = getChildFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.frameContainer, mFileListFragment);
transaction.commit();
}
}
Now In FrameLayout(id = frameContainer) of that BaseFragment I open child fragment that is FileListFragment. (fragment_file_list.xml)
fragment_file_list.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/rvFileList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible"/>
</RelativeLayout>
FileListFragment.java
public class FileListFragment extends Fragment{
private View mView;
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
if (mView == null) {
mView = inflater.inflate(R.layout.fragment_file_list, null);
setLayoutViews(mView);
}
return mView;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Here there is a server call which retrieves File Data from server. When I send server request I start progressBar and after response I hide progressBar programatically.
ProgressBar mProgressBar = new ProgressBar(activity);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.CENTER;
mProgressBar.setLayoutParams(params);
mProgressBar.getIndeterminateDrawable().setColorFilter(activity.getResources().getColor(R.color.colorPrimary), PorterDuff.Mode.MULTIPLY);
FrameLayout listFrame = getParentFragment().getView().findViewById(R.id.frameContainer);
if(listFrame != null) {
listFrame.addView(mProgressBar);
}
}
}
But it doesn't show progressBar in middle of the screen. It displays below of middle of screen like image attached below.
You can try with android:layout_gravity
Standard gravity constant that a child supplies to its parent.
You can align a view in center of the Framelayout by setting the layout_gravity of the child view .
android:layout_gravity="center"
Place the object in the center of its container in both the vertical and horizontal axis, not changing its size .
This is because you adding progressbar in center of framelayout, try this
<android.support.design.widget.CoordinatorLayout
android:id="#+id/myCoordinator"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
android:id="#+id/progressBar2"
style="?android:attr/progressBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
<android.support.design.widget.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<include layout="#layout/toolbar" />
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/frameContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<RelativeLayout
android:id="#+id/rlSearchToolContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#color/colorPrimary"
android:gravity="bottom"
android:layout_gravity="bottom"
android:visibility="gone">
<LinearLayout
android:id="#+id/llSearchComponentContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#color/colorPrimary"
android:layout_toLeftOf="#+id/btnDone"
android:gravity="bottom"
android:orientation="horizontal"></LinearLayout>
<Button
android:id="#+id/btnDone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="Done"/>
</RelativeLayout>
</android.support.design.widget.CoordinatorLayout>
<FrameLayout
android:id="#+id/frameLeftSlide"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start" />
Try it using Relativelayout, use Relativelayout as container of progressbar and use centerinparent attribute to center the progressbar in the middle of screen :
RelativeLayout layout = new RelativeLayout(this);
progressBar = new ProgressBar(this);
progressBar.setIndeterminate(true);
progressBar.setVisibility(View.VISIBLE);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(100,100);
params.addRule(RelativeLayout.CENTER_IN_PARENT);
layout.addView(progressBar,params);
setContentView(layout);
I've got a problem with databinding in android.
Above are xml file and activity class:
activity_main.xml ( the binding is in android:enabled="#{loginInfo.existingUser}")
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="loginInfo"
type="com.example.android.loginapplication.LoginInfo"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<RadioGroup
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/new_customer"
android:enabled="#{loginInfo.existingUser}"/>
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/i_have_a_password"/>
</RadioGroup>
<EditText
android:id="#+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"/>
</LinearLayout>
</layout>
LoginInfoActivity.java
public class LoginInfoActivity extends AppCompatActivity {
private LoginInfo loginInfo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LoginInfoBinding binding = DataBindingUtil.setContentView(
this, R.layout.activity_main);
binding.setLoginInfo(loginInfo);
}
}
it can't find generated class LoginInfoBinding in LoginInfoActivity...
is the xml correct? Or it depends by other things?
The binding class is named after the layout resource by default. Your layout resource is activity_main.xml, so the binding is ActivityMainBinding.