I'm making a music player and have implemented a marquee for the song and artist name. But as soon as the seek bar gets updated, the text view comes back to the original position. So in this way, a kind of back and forth motion of text is seen.
Here is my XML code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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:id="#+id/mainFullPlayerContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.musicplayer.integrated.sanket.music.MainFullPlayer"
android:background="#color/defaultBackground">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/relativeLayout"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true">
<ImageView
android:id="#+id/imageView_full_player_more"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_marginTop="20dp"
android:layout_marginRight="15dp"
app:srcCompat="#drawable/icon_more" />
</RelativeLayout>
<ImageView
android:id="#+id/imageView_full_player_album_art"
android:layout_width="300dp"
android:layout_height="300dp"
app:srcCompat="#drawable/default_album_art"
android:layout_marginTop="29dp"
android:layout_below="#+id/relativeLayout"
android:layout_centerHorizontal="true" />
<SeekBar
android:id="#+id/seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:progressTint="#color/defaultTextColor"
android:thumbTint="#color/defaultTextColor"
android:layout_above="#+id/imageView_full_player_play"
android:layout_marginBottom="37dp" />
<ImageView
android:id="#+id/imageView_full_player_play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="31dp"
app:srcCompat="#drawable/icon_play_small" />
<ImageView
android:id="#+id/imageView_full_player_next"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/imageView_full_player_play"
android:layout_marginStart="39dp"
android:layout_toEndOf="#+id/imageView_full_player_play"
app:srcCompat="#drawable/icon_fast_next_small" />
<ImageView
android:id="#+id/imageView_full_player_prev"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/imageView_full_player_play"
android:layout_marginEnd="38dp"
android:layout_toStartOf="#+id/imageView_full_player_play"
app:srcCompat="#drawable/icon_rewind_prev_small" />
<TextView
android:id="#+id/textView_full_player_song"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignEnd="#+id/imageView_full_player_album_art"
android:layout_alignStart="#+id/imageView_full_player_album_art"
android:layout_below="#+id/imageView_full_player_album_art"
android:layout_marginTop="12dp"
android:ellipsize="marquee"
android:focusable="true"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:singleLine="true"
android:text="Song Name"
android:textAlignment="center"
android:textColor="#color/defaultTextColor"
android:textSize="18sp" />
<TextView
android:id="#+id/textView_current_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0:00"
android:textColor="#color/defaultTextColor"
android:textSize="12sp"
android:layout_marginBottom="18dp"
android:layout_above="#+id/imageView_full_player_prev"
android:layout_alignStart="#+id/textView_full_player_artist" />
<TextView
android:id="#+id/textView_total_length"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="5:00"
android:textSize="12sp"
android:textColor="#color/defaultTextColor"
android:layout_alignBaseline="#+id/textView_current_time"
android:layout_alignBottom="#+id/textView_current_time"
android:layout_alignEnd="#+id/textView_full_player_artist" />
<TextView
android:id="#+id/textView_full_player_artist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignEnd="#+id/textView_full_player_song"
android:layout_alignStart="#+id/textView_full_player_song"
android:layout_below="#+id/textView_full_player_song"
android:layout_marginTop="12dp"
android:text="Artist"
android:textAlignment="center"
android:textColor="#color/defaultTextColor"
android:textSize="15sp"
android:ellipsize="marquee"
android:singleLine="true"
android:marqueeRepeatLimit="marquee_forever"
android:focusable="true"
android:scrollHorizontally="true"
/>
</RelativeLayout>
Here is my Java code:
public class MainFullPlayer extends AppCompatActivity {
private static RelativeLayout fullPlayer;
private static ImageView fullPlayer_play , fullPlayer_next ,
fullPlayer_prev,fullPlayer_album;
private static TextView fullPlayer_song , fullPlayer_artist ,
fullPlayer_currentTime , fullPlayer_maxTime;
private static SeekBar seekBar;
private Songs song;
private static Handler progressHandler;
private static Runnable progressRunnable;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_full_player);
fullPlayer = (RelativeLayout)findViewById(R.id.mainFullPlayerContainer);
fullPlayer_play = (ImageView)findViewById(R.id.imageView_full_player_play);
fullPlayer_next = (ImageView)findViewById(R.id.imageView_full_player_next);
fullPlayer_prev = (ImageView)findViewById(R.id.imageView_full_player_prev);
fullPlayer_album = (ImageView)findViewById(R.id.imageView_full_player_album_art);
fullPlayer_song = (TextView)findViewById(R.id.textView_full_player_song);
fullPlayer_artist = (TextView)findViewById(R.id.textView_full_player_artist);
fullPlayer_currentTime = (TextView)findViewById(R.id.textView_current_time);
fullPlayer_maxTime = (TextView)findViewById(R.id.textView_total_length);
fullPlayer_maxTime.setText(MusicPlayback.getTime(MusicPlayback.mediaPlayer.getDuration()));
seekBar = (SeekBar)findViewById(R.id.seekBar);
song = MusicPlayback.allTracks.get(MusicPlayback.songPosition);
fullPlayer_song.setSelected(true);
fullPlayer_artist.setSelected(true);
fullPlayer_song.setText(song.getSongName());
fullPlayer_artist.setText(song.getArtist());
if(MusicPlayback.getPlayingStatus()){
fullPlayer_play.setImageResource(R.drawable.icon_pause_small);
}
else
{
fullPlayer_play.setImageResource(R.drawable.icon_play_small);
}
if(song.getAlbumArt()!= null){
fullPlayer_album.setImageURI(Uri.parse(song.getAlbumArt()));
fullPlayer.setBackground(FragmentAllTracks.d);
}
else{
fullPlayer_album.setImageResource(R.drawable.default_album_art);
fullPlayer.setBackgroundColor(Color.argb(255, 48, 48, 48));
}
seekBar.setMax(MusicPlayback.mediaPlayer.getDuration());
progressHandler = new Handler();
progressRunnable = new Runnable() {
#Override
public void run() {
seekBar.setProgress(MusicPlayback.mediaPlayer.getCurrentPosition());
fullPlayer_currentTime.setText(MusicPlayback.getTime(MusicPlayback.mediaPlayer.getCurrentPosition()));
progressHandler.postDelayed(progressRunnable,100);
}
};
progressHandler.postDelayed(progressRunnable,100);
}
#Override
public void onBackPressed() {
super.onBackPressed();
this.overridePendingTransition(R.anim.left_exit_translate,R.anim.right_exit_translate);
}
}
Here is the result:
Try to use this MarqueeTextView class, it automatically set fixed size for TextView so it won't re-measure (the reason cause restart scroll animation):
public class MarqueeTextView extends AppCompatTextView implements View.OnLayoutChangeListener {
public MarqueeTextView(Context context) {
this(context, null);
}
public MarqueeTextView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MarqueeTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setSingleLine();
setEllipsize(TextUtils.TruncateAt.MARQUEE);
setMarqueeRepeatLimit(-1);
setSelected(true);
addOnLayoutChangeListener(this);
}
#Override
public boolean isFocused() {
return true;
}
#Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
if (hasWindowFocus) super.onWindowFocusChanged(hasWindowFocus);
}
#Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
if (focused) super.onFocusChanged(focused, direction, previouslyFocusedRect);
}
#Override
public void onLayoutChange(View v, int left, int top, int right, int bottom,
int oldLeft, int oldTop, int oldRight, int oldBottom) {
ViewGroup.LayoutParams layoutParams = getLayoutParams();
layoutParams.height = bottom - top;
layoutParams.width = right - left;
removeOnLayoutChangeListener(this);
setLayoutParams(layoutParams);
}
}
I had the same problem. It happens because of this line inside the runnable:
fullPlayer_currentTime.setText(MusicPlayback.getTime(MusicPlayback.mediaPlayer.getCurrentPosition()));
I found the answer here: https://stackoverflow.com/a/13841982/10334697.
You have to set fixed size for your TextView.
I think its because of focus. Please set your textview like this
<TextView
android:id="#+id/textView_full_player_song"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignEnd="#+id/imageView_full_player_album_art"
android:layout_alignStart="#+id/imageView_full_player_album_art"
android:layout_below="#+id/imageView_full_player_album_art"
android:layout_marginTop="12dp"
android:singleLine="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit ="marquee_forever"
android:focusable="true"
android:focusableInTouchMode="true"
android:scrollHorizontally="true"
android:text="Song Name"
android:textAlignment="center"
android:textColor="#color/defaultTextColor"
android:textSize="18sp" />
add this your TextView,
android:focusable="true"
android:focusableInTouchMode="true"
Related
I have my custom BottomSheetDialogFragment.Inside this dialog I have custom edittext and recyclerview.My goal is to move reyclerview above a keyboard,when it' showing. Here is a my custom edittext code
public class WrappedEditText extends android.support.v7.widget.AppCompatEditText {
public WrappedEditText(Context context) {
super(context);
}
public WrappedEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public WrappedEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Nullable
private View wrapper;
#Nullable
public View getWrapper() {
return wrapper;
}
#Override
public void getFocusedRect(Rect r) {
if (wrapper != null) {
wrapper.getFocusedRect(r);
return;
}
super.getFocusedRect(r);
}
#Override
public boolean getGlobalVisibleRect(Rect r, Point globalOffset) {
if (wrapper != null)
return wrapper.getGlobalVisibleRect(r, globalOffset);
return super.getGlobalVisibleRect(r, globalOffset);
}
public void setWrapper(#Nullable View wrapper) {
this.wrapper = wrapper;
}
I'm using this code like this
searchView.setWrapper(rootView);
searchView.setOnFocusChangeListener((view1, b) -> {
if(searchView.getWrapper()==null)
searchView.setWrapper(rootView);
});
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/root_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#drawable/slide_menu_background"
android:orientation="vertical">
<RelativeLayout
android:id="#+id/close_view"
android:layout_width="wrap_content"
android:layout_height="#dimen/dimen_p_30"
android:layout_centerHorizontal="true"
android:layout_gravity="center"
android:orientation="vertical">
<View
android:layout_width="#dimen/dimen_p_40"
android:layout_height="#dimen/dimen_p_4"
android:layout_alignParentTop="true"
android:layout_marginTop="#dimen/dimen_p_10"
android:background="#drawable/slide_menu_title_line" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/title_conainer"
android:layout_width="match_parent"
android:layout_height="#dimen/dimen_p_30"
android:layout_below="#+id/close_view">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/dimen_p_30"
android:fontFamily="#font/myriad_geo_medium"
android:text="#string/insert_gif"
android:textColor="#color/black"
android:textSize="#dimen/dimen_p_14" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/search_layout"
android:layout_width="match_parent"
android:layout_height="#dimen/dimen_p_38"
android:layout_below="#+id/title_conainer"
android:layout_marginLeft="#dimen/dimen_p_30"
android:layout_marginRight="#dimen/dimen_p_30"
android:background="#drawable/rounded_corners_white">
<ImageView
android:id="#+id/search_icon"
android:layout_width="#dimen/dimen_p_24"
android:layout_height="#dimen/dimen_p_24"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="#dimen/dimen_p_8"
android:background="#mipmap/search_icon" />
<app.singltone.giphy.WrappedEditText
android:id="#+id/search_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:layout_gravity="center"
android:layout_marginLeft="#dimen/dimen_p_35"
android:layout_marginRight="#dimen/dimen_p_10"
android:background="#null"
android:fontFamily="#font/myriad_geo_medium"
android:gravity="center_vertical"
android:hint="#string/find_gif"
android:imeOptions="actionSearch"
android:inputType="textNoSuggestions"
android:singleLine="true"
android:textColor="#color/black"
android:textColorHint="#59000000"
android:textSize="#dimen/dimen_p_14" />
</RelativeLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/search_layout"
>
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:saveEnabled="true" />
</android.support.v4.widget.NestedScrollView>
</RelativeLayout>
rootView is a main view in xml file.This code working perfect only first time,but when user closed keyboard and then opened it again ,this code does not working.
Is a any way to solve this problem? or is this a correct solution?
Thanks
I inherited some big project with a lot of legacy code and now I'm facing some weird stuff..
I need to make this screen have recyclerview with grid layout manager, 2 columns. This is what I get. Is there a way to center those icons in the middle of the screen? I tried with gravity, but nothing works. Maybe there is some thing inside all that legacy code that is making problem or this is just recyclerView's issue?
This is the item's layout (terrible, don't ask..)
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/color_view_controller_item_background"
android:orientation="vertical">
<TextView
android:id="#+id/textViewSceneKK"
android:layout_width="match_parent"
android:layout_height="#dimen/room_button_height"
android:layout_gravity="center"
android:layout_marginLeft="#dimen/row_filter_text_margin_left"
android:layout_marginRight="#dimen/row_filter_text_margin_left"
android:gravity="center"
android:shadowDx="-1"
android:shadowDy="-1"
android:shadowRadius="1"
android:textSize="#dimen/row_scene_kk_text_size" />
<TextView
android:id="#+id/textViewSceneName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="#dimen/row_filter_text_margin_bottom"
android:layout_marginLeft="#dimen/row_filter_text_margin_left"
android:layout_marginRight="#dimen/row_filter_text_margin_left"
android:layout_marginTop="#dimen/row_filter_text_margin_top"
android:clickable="false"
android:gravity="center"
android:longClickable="false"
android:textColor="#color/main_text_color"
android:textSize="#dimen/row_browser_right_name_text_size" />
</LinearLayout>
<!--<View-->
<!--android:id="#+id/filterView"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="match_parent"-->
<!--android:clickable="false"-->
<!--android:longClickable="false" />-->
<View
android:id="#+id/filterViewClick"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:selectableItemBackground"
android:focusable="false"
android:focusableInTouchMode="false" />
And fragment't layout:
<customview.CustomRecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none" />
And the code:
customRecyclerView.setHasFixedSize(false);
customRecyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2));
customRecyclerView.addItemDecoration(new DividerItemDecoration(getContext(),
R.drawable.line_separator_empty, DividerItemDecoration.VERTICAL_LIST));
customRecyclerView.setAdapter(adapter);
CustomRecyclerView.java
public class CustomRecyclerView extends RecyclerView {
private boolean enableScroll = true;
public CustomRecyclerView(Context context) {
super(context);
}
public CustomRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public boolean isEnableScroll() {
return enableScroll;
}
public void setEnableScroll(boolean enableScroll) {
this.enableScroll = enableScroll;
}
#Override
public int computeVerticalScrollRange() {
return super.computeVerticalScrollRange();
}
#Override
public boolean onInterceptTouchEvent(MotionEvent e) {
if (enableScroll) {
return super.onInterceptTouchEvent(e);
}
return false;
}
}
You have to use layout gravity to make it center & need to change match-parent to wrap_content, also you have to assign layout gravity runtime. try this code:
Adapter item layout:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:descendantFocusability="blocksDescendants"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:id="#+id/top_header_rl"
android:background="#color/app_header_color"
android:orientation="vertical">
<TextView
android:id="#+id/textViewSceneKK"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:gravity="center"
android:shadowDx="-1"
android:shadowDy="-1"
android:shadowRadius="1"
android:text="Heder name"
android:textSize="26sp" />
<TextView
android:id="#+id/textViewSceneName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:clickable="false"
android:gravity="center"
android:text="Footer name"
android:longClickable="false"
android:textSize="25sp" />
</LinearLayout>
<!--<View-->
<!--android:id="#+id/filterView"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="match_parent"-->
<!--android:clickable="false"-->
<!--android:longClickable="false" />-->
<View
android:id="#+id/filterViewClick"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="?android:selectableItemBackground"
android:focusable="false"
android:focusableInTouchMode="false" />
</FrameLayout>
Adapter Code:
public class CenterGridView extends RecyclerView.Adapter<CenterGridView.CenterGridViewViewHolder> {
private Context context;
public CenterGridView(Context context){
this.context =context;
}
#Override
public CenterGridViewViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new CenterGridViewViewHolder(LayoutInflater.from(context).inflate(R.layout.new_tiem,parent,false));
}
#Override
public void onBindViewHolder(CenterGridViewViewHolder holder, int position) {
if(position%2==0){
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.RIGHT;
holder.top_header_rl.setLayoutParams(params);
}else{
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.LEFT;
holder.top_header_rl.setLayoutParams(params);
}
}
#Override
public int getItemCount() {
return 20;
}
class CenterGridViewViewHolder extends RecyclerView.ViewHolder{
private LinearLayout top_header_rl;
public CenterGridViewViewHolder(View itemView) {
super(itemView);
top_header_rl = (LinearLayout)itemView.findViewById(R.id.top_header_rl);
}
}
}
Main Activity layout:
<?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:gravity="center_horizontal"
android:orientation="vertical">
<com.demostudies.CustomRecyclerView
android:id="#+id/tests"
android:layout_width="wrap_content"
android:layout_height="wrap_content"></com.demostudies.CustomRecyclerView>
</LinearLayout>
// Set Adapter
CustomRecyclerView customRecyclerView = (CustomRecyclerView)findViewById(R.id.tests);
customRecyclerView.setHasFixedSize(false);
customRecyclerView.setLayoutManager(new GridLayoutManager(this, 2));
customRecyclerView.setAdapter(new CenterGridView(this));
try this:
it's working for me
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|center_vertical"
>
</androidx.recyclerview.widget.RecyclerView>
I have implemented a custom view like this:
public class HeaderView extends LinearLayout {
#Bind(R.id.bill_summary_layout)
LinearLayout summaryLayout;
#Bind(R.id.bill_balance)
TextView balance;
#Bind(R.id.bill_closedate)
TextView closedDate;
#Bind(R.id.bill_status)
TextView status;
#Bind(R.id.bill_partial_overdue)
ViewStub partialOverdueView;
#Bind(R.id.bill_partial_closed)
ViewStub partialClosedView;
#Bind(R.id.bill_partial_open)
ViewStub partialOpenView;
Bill bill;
public HeaderView(Context context) {
super(context);
initUI(context);
}
public HeaderView(Context context, AttributeSet attrs) {
super(context, attrs);
initUI(context);
}
public HeaderView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initUI(context);
}
private void initUI(Context context) {
LayoutInflater.from(context).inflate(R.layout.header_view, this);
}
public Bill getBill() {
return bill;
}
public void setBill(Bill bill) {
this.bill = bill;
notifyMustRebind();
}
public void notifyMustRebind() {
setupUI();
}
private void setupUI() {
if(this.bill == null)
throw new RuntimeException("O objeto bill tem que estar setado e nao ser nulo. Talvez esqueceu de chamar o setBill?");
switch (bill.getState()) {
case OVERDUE:
setOverdueState();
break;
case OPEN:
setOpenState();
break;
case CLOSED:
setClosedState();
break;
case FUTURE:
setFutureState();
break;
}
}
private void setOverdueState(){
summaryLayout.setBackgroundColor(ContextCompat.getColor(getContext(),R.color.overdue));
LayoutInflater.from(getContext()).inflate(R.layout.partial_overdue_view, this, true);
partialOverdueView.inflate();
}
private void setOpenState(){
summaryLayout.setBackgroundColor(ContextCompat.getColor(getContext(),R.color.open));
partialOpenView.inflate();
}
private void setClosedState(){
summaryLayout.setBackgroundColor(ContextCompat.getColor(getContext(),R.color.closed));
partialClosedView.inflate();
}
private void setFutureState(){
summaryLayout.setBackgroundColor(ContextCompat.getColor(getContext(),R.color.future));
}
#Override
protected void onFinishInflate() {
super.onFinishInflate();
ButterKnife.bind(this);
}
#Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
ButterKnife.unbind(this);
}
}
The header_view.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">
<LinearLayout
android:id="#+id/bill_summary_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/bg_content_arrow"
android:backgroundTint="#color/colorAccent"
android:orientation="vertical"
android:paddingBottom="#dimen/header_margin"
android:paddingTop="#dimen/header_margin"
>
<TextView
android:id="#+id/bill_balance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingBottom="#dimen/header_text_margin"
android:text="R$ 2.300,10"
android:textColor="#android:color/white"
android:textSize="22sp"
android:textStyle="bold"
/>
<TextView
android:id="#+id/bill_closedate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingBottom="#dimen/header_text_margin"
android:text="Vencimento 15 MAI"
android:textColor="#android:color/white"
android:textSize="18sp"
/>
<TextView
android:id="#+id/bill_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingBottom="#dimen/header_text_margin"
android:text="Fechamento em 5 de Julho"
android:textAllCaps="true"
android:textColor="#android:color/white"
android:textSize="12sp"
/>
</LinearLayout>
<ViewStub
android:id="#+id/bill_partial_overdue"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout="#layout/partial_overdue_view"
/>
<ViewStub
android:id="#+id/bill_partial_closed"
layout="#layout/partial_closed_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ViewStub
android:id="#+id/bill_partial_open"
layout="#layout/partial_open_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#color/colorAccent"/>
</LinearLayout>
The view above is inside another view called bill_view:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<br.com.leonardo2204.nubanktest.ui.custom.HeaderView
android:id="#+id/header_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="#dimen/list_header_padding">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:paddingLeft="#dimen/list_header_padding"
android:paddingStart="#dimen/list_header_padding"
android:text="De 5 Mar até 5 abr"
android:textAllCaps="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:paddingEnd="#dimen/list_header_padding"
android:paddingRight="#dimen/list_header_padding"
android:text="Valores em R$"
android:textAllCaps="true" />
</RelativeLayout>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
The view above is inflated inside a PagerAdapter, as this:
#Override
public Object instantiateItem(ViewGroup container, int position) {
View v = LayoutInflater.from(container.getContext()).inflate(R.layout.bill_view, container, false);
HeaderView header = (HeaderView) v.findViewById(R.id.header_view);
header.setBill(billList.get(position));
container.addView(v);
return v;
}
The problem is, I'm getting the stack trace below :
Process: br.com.leonardo2204.nubanktest, PID: 10815
java.lang.IllegalArgumentException: ViewStub must have a valid layoutResource
at android.view.ViewStub.inflate(ViewStub.java:289)
at br.com.leonardo2204.nubanktest.ui.custom.HeaderView.setClosedState(HeaderView.java:112)
at br.com.leonardo2204.nubanktest.ui.custom.HeaderView.setupUI(HeaderView.java:91)
at br.com.leonardo2204.nubanktest.ui.custom.HeaderView.notifyMustRebind(HeaderView.java:76)
at br.com.leonardo2204.nubanktest.ui.custom.HeaderView.setBill(HeaderView.java:72)
at br.com.leonardo2204.nubanktest.ui.adapter.ViewPagerAdapter.instantiateItem(ViewPagerAdapter.java:30)
at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:870)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1086)
at android.support.v4.view.ViewPager.populate(ViewPager.java:952)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1474)
at android.view.View.measure(View.java:17547)
What I am doing wrong ? Is there a better approach to inflate the header view other than inside instantiateView ?
Thanks !
USE
android:layout="#layout/xyz"
instead of
layout="#layout/xyz"
i have a library to insert floating buttons in a layout (http://prolificinteractive.com/blog/2014/07/24/android-floating-action-button-aka-fab/)
Then, i have this layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:fontawesometext="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginTop="32dp"
android:layout_marginBottom="16dp"
android:layout_marginRight="16dp">
<com.beardedhen.androidbootstrap.FontAwesomeText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="4dp"
android:textSize="45sp"
android:textColor="#737373"
android:id="#+id/faIcon"
fontawesometext:fa_icon="fa-question" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text='"texto de ejemplo de pregunta"'
android:id="#+id/tvQuestion"
android:textColor="#color/primary"
android:textStyle="bold"
android:textSize="28sp"
android:typeface="monospace"
android:layout_marginLeft="16dp"
android:layout_marginTop="32dp"
android:layout_marginBottom="16sp" />
</LinearLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/frameConainter"
android:background="#color/dark_grey" />
</LinearLayout>
And i need to set the center of the button in the middle of framelayout top, like as the left image:
I have this in a custom view:
public class YesNoReplyView extends ReplyParentView {
private FloatingActionButton buttonYes;
private FloatingActionButton buttonNo;
public YesNoReplyView(Context context) {
super(context);
}
public YesNoReplyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
public YesNoReplyView(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public void initializeComponents() {
int[] position = new int[2];
getLocationOnScreen(position);
buttonYes = new FloatingActionButton.Builder((Activity)getContext())
.withDrawable(getResources().getDrawable(R.drawable.ic_plus))
.withButtonColor(getResources().getColor(R.color.green_success))
.withGravity(Gravity.BOTTOM | Gravity.RIGHT)
.withMargins(0, 0, 16, 16)
.create();
buttonNo = new FloatingActionButton.Builder((Activity)getContext())
.withDrawable(getResources().getDrawable(R.drawable.ic_plus))
.withButtonColor(getResources().getColor(R.color.primary))
.withGravity(Gravity.BOTTOM | Gravity.RIGHT)
.withMargins(0, 0, 26, 26)
.create();
}
#Override
public String getResult() {
String result = "";
return result;
}
}
But i dont know how can i calculate the margins from the coordinates to set the view in the position i want..
Anyone knows any way better to do it this?(I cant use a XML layout..)
I have a LinearLayout which has its margins cut off and I've tried fiddling around with the XML as well as the FlyOutContainer class in order to fix it, no luck.
I want my LinearLayout to fit on any android screen. Can anyone point me in the right direction on how to fix this problem? And can anyone explain to me why the margins are being cut off, so if this happens again I know what to do?
Here is what my LinearLayout menu looks like:
Here is the FlyOutContainer class:
public class FlyOutContainer extends LinearLayout {
private View menu; //Menu of application
private View content; //Content of application
protected static final int menuMargin = 150;
public enum MenuState {
CLOSED, OPEN
};
protected int currentContentOffset = 0;
protected MenuState menuCurrentState = MenuState.CLOSED;
public FlyOutContainer(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public FlyOutContainer(Context context, AttributeSet attrs) {
super(context, attrs);
}
public FlyOutContainer(Context context) {
super(context);
}
#Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
this.menu = this.getChildAt(0);
this.content = this.getChildAt(1);
this.menu.setVisibility(View.GONE);
}
#Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
if (changed)
this.calculateChildDimensions();
this.menu.layout(left, top, right - menuMargin, bottom);
this.content.layout(left + this.currentContentOffset, top, right
+ this.currentContentOffset, bottom);
}
public void toggleMenu() {
switch (this.menuCurrentState) {
case CLOSED:
this.menu.setVisibility(View.VISIBLE);
this.currentContentOffset = this.getMenuWidth();
this.content.offsetLeftAndRight(currentContentOffset); this.menuCurrentState = MenuState.OPEN;
break;
case OPEN:
this.content.offsetLeftAndRight(-currentContentOffset);
this.currentContentOffset = 0;
this.menuCurrentState = MenuState.CLOSED;
this.menu.setVisibility(View.GONE);
break;
}
this.invalidate();
}
private int getMenuWidth() {
return this.menu.getLayoutParams().width;
}
private void calculateChildDimensions() {
this.content.getLayoutParams().height = this.getHeight();
this.content.getLayoutParams().width = this.getWidth();
this.menu.getLayoutParams().width = this.getWidth() - menuMargin;
this.menu.getLayoutParams().height = this.getHeight();
}
}
Here is my XML:
<FlyOutContainer.FlyOutContainer xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:facebook="http://schemas.android.com/apk/res-auto"
style="#style/Container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/menu_Child"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#000000"
android:orientation="vertical" >
<com.facebook.widget.ProfilePictureView
android:id="#+id/profilePicture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
facebook:is_cropped="true"
facebook:preset_size="small" />
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="toggleMenu"
android:text="#string/button_1" />
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="toggleMenu"
android:text="#string/button_2" />
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="toggleMenu"
android:text="#string/button_3" />
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="toggleMenu"
android:text="#string/button_4" />
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="toggleMenu"
android:text="#string/button_5" />
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="toggleMenu"
android:text="#string/button_6" />
</LinearLayout>
<!-- The navigation drawer -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#android:color/transparent"
android:gravity="center"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/defined_Text" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="toggleMenu"
android:text="#string/Toggle_Menu" />
</LinearLayout>
Would appreciate any guidance.
So I fixed the problem by taking out style="#style/Container out of my XML, for some weird reason my theme which is custom made was making extra padding on all four sides of the Layout.
So in summary changing XML to this fixed it:
<FlyOutContainer.FlyOutContainer xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:facebook="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent" >
....
....
....
</FlyOutContainer.FlyOutContainer>
IMPROVED ANSWER:
What's the point of UI design if you can't keep your background right :) ? In order to keep the style I had previously implemented I saw that in my styles.xml in res there was an extra padding of this 16 dp like so:
<style name="Container" >
<item name="android:layout_margin">0dp</item>
<item name="android:padding">16dp</item> <!-- REMOVE HERE!!! -->
<item name="android:orientation">vertical</item>
<item name="android:background">#drawable/background</item>
</style>
removing that line allowed me to keep my background