I have been working on an app and can't get EditText into an xml file.
I had it working, then I added a ScrollView and it didn't work at all so I deleted it and now it spreads out the groups throughout the screen, and I can't fix it.
PlayScreen.java
/**
* Created by Gavin on 8/10/2016.
*/
public class PlayScreen extends Activity {
public EditText numberOP;
private RelativeLayout layout;
private int i = 0;
private int x = 0;
private int y = 1;
private int z = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.layout_play);
numberOP = (EditText) findViewById(R.id.number_of_players);
layout = (RelativeLayout) findViewById(R.id.layout_play_id);
}
public void onEnterClickOne(View view) {
/**if(textView != null) {
layout.removeView(textView);
}
if(editText != null) {
layout.removeView(editText);
}*/
int b = 0;
if(i+y+x+z != 0) {
for (b = 0; b < i + y + x + z * 100; b++) {
System.out.println(b);
View v = findViewById(b);
if (v != null) {
layout.removeView(v);
}
}
}
i = 0;
x = 0;
y = 1;
z = 1;
if (numberOP.getText().toString().length() > 0) {
int length = Integer.parseInt(numberOP.getText().toString())*2;
for (i = 0; i < length; i++) {
if (i % 2 == 0) {
x++;
TextView textView = new TextView(PlayScreen.this);
textView.setId(x*30);
textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT));
textView.setText(String.format("Group: %s", Integer.toString(x)));
textView.setTextSize(20);
textView.setTypeface(null,Typeface.BOLD);
layout.addView(textView);
}
EditText editText = new EditText(PlayScreen.this);
editText.setId(i+1);
editText.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT));
if(y == 1) {
editText.setHint("Partner 1");
y++;
} else if(y == 2) {
editText.setHint("Partner 2");
y--;
}
layout.addView(editText);
}
}
}
}
layout_play.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:background="#f7f7f7"
android:id="#+id/layout_play_id"
android:padding="25dp">
<TextView
android:text="#string/choose_your_partners"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="31sp"
android:layout_centerHorizontal="true"
android:id="#+id/editTextTwo" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="numberSigned"
android:ems="10"
android:hint="#string/number_of_groups"
android:id="#+id/number_of_players"
android:layout_below="#+id/editTextTwo"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/button_1_text"
android:textSize="30sp"
android:id="#+id/playButton"
android:onClick="onEnterClickOne"
android:layout_below="#+id/number_of_players"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
Also, if you have any suggestions for ScrollView, that'd be awesome. Thanks.
The Problem
For such kind of view component, it is better to use LinearLayout with vertically orientation, to easily put the view component inside this.
RelativeLayout:
RelativeLayout enables you to specify how child views are positioned relative to each other. The position of each view can be specified as relative to sibling elements or relative to the parent.
LinearLayout:
LinearLayout is a view group that aligns all children in either vertically or horizontally.
Related
I'm working on a quiz app where there is one question and five radio buttons per CardView in a RecyclerView. Each radio button has an assigned score.
For Example, there are two CardViews
CardView #1
radio_button_1 = -20
radio_button_2 = -10
radio_button_3 = 0
radio_button_4 = 10
radio_button_5 = 20
CardView #2
radio_button_1 = -20
radio_button_2 = -10
radio_button_3 = 0
radio_button_4 = 10
radio_button_5 = 20
Say user picks radio_button_1 on CardView #1 and he picks radio_button_3 on CardView #2 and so forth. I want to add the points between CardViews and be able to preserve/ save those points as user scrolls through the CardViews. I don't know how it works with RecyclerView. SharedPreferences?
I have added a text view to test and see if the score is being updated in the background with the new score.
Recycler Adapter:
public class MainAdapter extends RecyclerView.Adapter<MainAdapter.ViewHolder> {
private List<App> mApps;
public static int score;
public static int updateScore() {
return score;
}
public MainAdapter(List<App> apps) {
mApps = apps;
}
#Override
public MainAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.cards_adapter, parent, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
#Override
public int getItemViewType(int position) {
return (position);
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
App app = mApps.get(position);
holder.questionTextView.setText(app.getQuestion());
}
#Override
public int getItemCount() {
return mApps.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView questionTextView;
private TextView titleTextView;
public RadioGroup radioGroup;
public RadioButton rb1, rb2, rb3, rb4, rb5;
public ViewHolder(View itemView) {
super(itemView);
radioGroup = itemView.findViewById(R.id.radio_group);
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
int selectedValue = 0;
switch (checkedId) {
case R.id.radio_button_1:
selectedValue -= 20;
break;
case R.id.radio_button_2:
selectedValue -= 10;
break;
case R.id.radio_button_3:
selectedValue += 0;
break;
case R.id.radio_button_4:
selectedValue += 10;
break;
case R.id.radio_button_5:
selectedValue += 20;
break;
}
updateValue (selectedValue);
}
public int updateValue(int selectedValue) {
/**Only to test if value is being tallied**/
TextView valueView = titleTextView.findViewById(R.id.title);
valueView.setText(String.valueOf(selectedValue));
return selectedValue;
}
});
questionTextView = itemView.findViewById(R.id.question);
titleTextView = itemView.findViewById(R.id.title);
rb1 = itemView.findViewById(R.id.radio_button_1);
rb2 = itemView.findViewById(R.id.radio_button_2);
rb3 = itemView.findViewById(R.id.radio_button_3);
rb4 = itemView.findViewById(R.id.radio_button_4);
rb5 = itemView.findViewById(R.id.radio_button_5);
}
#Override
public void onClick(View v) {
Log.d("App", mApps.get(getAdapterPosition()).getQuestion());
}
}}
MainActivity:
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private RecyclerView.LayoutManager mLayoutManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = findViewById(R.id.recycler_view);
SnapHelper snapHelper = new PagerSnapHelper();
snapHelper.attachToRecyclerView(mRecyclerView);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
mRecyclerView.setLayoutManager(mLayoutManager);
setupMainAdapter();
}
private void setupMainAdapter() {
List<App> apps = getApps();
MainAdapter adapter = new MainAdapter(apps);
mRecyclerView.setAdapter(adapter);
}
private List<App> getApps() {
List<App> apps = new ArrayList<>();
apps.add(new App((getResources().getString(R.string.question_1))));
apps.add(new App((getResources().getString(R.string.question_2))));
apps.add(new App((getResources().getString(R.string.question_3))));
apps.add(new App((getResources().getString(R.string.question_4))));
apps.add(new App((getResources().getString(R.string.question_5))));
apps.add(new App((getResources().getString(R.string.question_6))));
apps.add(new App((getResources().getString(R.string.question_7))));
apps.add(new App((getResources().getString(R.string.question_8))));
apps.add(new App((getResources().getString(R.string.question_9))));
apps.add(new App((getResources().getString(R.string.question_10))));
return apps;
}
}
CardView XML
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="275dp"
android:layout_height="575dp"
android:layout_margin="16dp"
card_view:cardBackgroundColor="#color/colorAccent"
card_view:cardCornerRadius="0dp"
card_view:cardElevation="8dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:fontFamily="#font/futura_medium"
android:padding="24dp"
android:textColor="#000000"
android:textSize="32sp"
tools:text="#string/title" />
<TextView
android:id="#+id/question"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/title"
android:layout_centerHorizontal="true"
android:fontFamily="#font/futura_medium"
android:textColor="#000000"
android:textSize="18sp"
tools:text="#string/question" />
<RadioGroup
android:id="#+id/radio_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/question"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_margin="16dp"
android:orientation="horizontal">
<RadioButton
android:id="#+id/radio_button_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:buttonTint="#color/colorPrimaryDark"
android:text="-2"
android:textColor="#000000" />
<RadioButton
android:id="#+id/radio_button_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:buttonTint="#color/colorPrimaryDark"
android:text="-1"
android:textColor="#000000" />
<RadioButton
android:id="#+id/radio_button_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:buttonTint="#color/colorPrimaryDark"
android:text="0"
android:textColor="#000000" />
<RadioButton
android:id="#+id/radio_button_4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:buttonTint="#color/colorPrimaryDark"
android:text="1"
android:textColor="#000000" />
<RadioButton
android:id="#+id/radio_button_5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:buttonTint="#color/colorPrimaryDark"
android:text="2"
android:textColor="#000000" />
</RadioGroup>
<com.google.android.material.button.MaterialButton
android:id="#+id/submit_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_margin="16dp"
android:layout_marginBottom="32dp"
android:fontFamily="#font/futura_medium"
android:text="#string/submit"
android:textColor="#color/colorAccent"
android:textSize="16sp"
app:backgroundTint="#color/colorPrimaryDark"
app:rippleColor="#color/colorPrimary" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
You can declare an interface inside MainAdapter, lets call it ScoreUpdatesListener. It has one method that will be called whenever you want to update the textView.
You will need to implement that interface in your MainActivity, you may do it anonymously, or have the class itself implements that interface. like class MainActivity implements MainAdapter.ScoreUpdatesListener {}.
Either way, you need to pass that interface implementation to the adapter and save its reference. You may do it in the constructor, or add a set method to the adapter.
Now, when updating viewHolder's value, call that listener and it will update the textView from the activity.
class MainAdaptaer {
private ScoreUpdates listener;
...
class ViewHolder... {
...
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
int selectedValue = 0;
switch (checkedId) {
case R.id.radio_button_1:
selectedValue -= 20;
break;
case R.id.radio_button_2:
selectedValue -= 10;
break;
case R.id.radio_button_3:
selectedValue += 0;
break;
case R.id.radio_button_4:
selectedValue += 10;
break;
case R.id.radio_button_5:
selectedValue += 20;
break;
}
score += selectedValue;
// score is an existing attribute of MainAdapter
// it can and should be non static attribute
listener.updateScore(score);
}
}
interface ScoreUpdatesListener {
void onScoreUpdate(int score);
}
}
In your activity:
private void setupMainAdapter() {
List<App> apps = getApps();
MainAdapter adapter = new MainAdapter(apps, new MainAdapter.ScoreUpdatesListener() {
#Override
public void onScoreUpdate(int score) {
TextView valueView = titleTextView.findViewById(R.id.title);
valueView.setText(String.valueOf(score));
}
});
mRecyclerView.setAdapter(adapter);
}
If the class itself implemented the interface, just pass this to the adapter.
You don't have to move the TextView handling to the activity, but you should. The adapter shouldn't mess with views that isn't ViewHolders
Im trying to set wrap text around image in one of my Fragments but it isn't working. Can somebody help me to solve this issue?
code in xml Fragment4
<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"
tools:context="make.appaplication.Fragment4">
<!-- TODO: Update blank fragment layout -->
<ImageView
android:layout_width="150dp"
android:layout_height="150dp"
android:src="#drawable/nature"
android:id="#+id/imageView"
android:layout_weight="1"
android:layout_marginRight="17dp"
android:layout_marginEnd="17dp"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<TextView
android:id="#+id/textView3"
android:textSize="17dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/text_page_1"
android:layout_below="#+id/textView5"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
code in class MyLeadingMarginSpan2
public class MyLeadingMarginSpan2 implements LeadingMarginSpan.LeadingMarginSpan2 {
private int margin;
private int lines;
private boolean wasDrawCalled = false;
private int drawLineCount = 0;
public MyLeadingMarginSpan2(int lines, int margin) {
this.margin = margin;
this.lines = lines;
}
#Override
public int getLeadingMargin(boolean first) {
boolean isFirstMargin = first;
// a different algorithm for api 21+
if (Build.VERSION.SDK_INT >= 21) {
this.drawLineCount = this.wasDrawCalled ? this.drawLineCount + 1 : 0;
this.wasDrawCalled = false;
isFirstMargin = this.drawLineCount <= this.lines;
}
return isFirstMargin ? this.margin : 0;
}
#Override
public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, int top, int baseline, int bottom, CharSequence text, int start, int end, boolean first, Layout layout) {
this.wasDrawCalled = true;
}
#Override
public int getLeadingMarginLineCount()
{
return this.lines;
}
}
and code in class Fragment4
String text = getString(R.string.text_page_1);
SpannableString ss = new SpannableString(text);
Drawable dIcon = ContextCompat.getDrawable(getActivity(),R.drawable.nature);
int rightMargin = dIcon.getIntrinsicWidth() + 10;
ss.setSpan(new MyLeadingMarginSpan2(3, rightMargin), 0, ss.length(), 0);
final TextView messageView = (TextView) view.findViewById(R.id.textView3);
messageView.setText(ss);
Here is what I have now
My requirements: create "incoming bubble" with width by content and max width 90%.
I have this markup:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="1.0"
tools:background="#color/white_smoke">
<LinearLayout
android:id="#+id/flBubble"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:background="#drawable/bubble_in"
android:layout_weight="0.9">
<ImageView
android:id="#+id/ivSay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:contentDescription="#string/default_content_description"
android:padding="8dp"
android:src="#drawable/ic_play_circle_outline_black_24dp"
android:tint="#color/primary"/>
<TextView
android:id="#+id/tvValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="8dp"
android:textColor="#color/black"
android:textSize="16sp"
tools:text="I would like to go to an Italian restaurant"/>
</LinearLayout>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0.1"/>
</LinearLayout>
Sometimes I get the following result:
But I expect the following result (it's falsely encouraging screenshot from Android Studio preview):
How can I prevent breaking word restaraunt by letters?
UPDATE
Although I use minSdk=15 I tried to use breakStrategy and I haven't get expected result.
android:breakStrategy="simple":
android:breakStrategy="balanced":
I found a related question: Force next word to a new line if the word is too long for the textview, but I didn't undestand how can I get maximum available width for TextView with layout_width="wrap_content?
It would be great if I could override the TextView.setText and place line breaks there if needed.
OMG, there were in my string!
value.replaceAll("\\s", " ");
Thank you all!
Use MaxWidth property for textview or else you should provide width for textview
<com.custom.views.CustomTextView
android:id="#+id/txt_send_chat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
android:maxWidth="250dp"
android:textColor="#color/color_chat_sender"
android:textSize="16sp"
app:font_name="#string/font_roboto_regular" />
You can use webview to achieve this behavior.
In webview you can use css to adjust text.
Take a look at this answer
Update
You can calculate width of string and add \n to string where is string needs to split
Rect bounds = new Rect();
Paint textPaint = textView.getPaint();
textPaint.getTextBounds(text, 0, text.length(), bounds);
int height = bounds.height();
int width = bounds.width();
Results is in pixels, so just check width of your view or screen and split the string.
UPDAE2: Example Code
I just wrote an example with simple layout in activity onCreate you can implement it in adapter or whatever works for you.
TextView textView = (TextView) findViewById(R.id.txt); //textview with empty text
Rect bounds = new Rect();
Paint textPaint = textView.getPaint();
String text = "some long text here.....";// text data to work on
textPaint.getTextBounds(text, 0, text.length(), bounds);
int textWidth = bounds.width();// get text width in pixel
int marginPadding = 100;// we have some padding and margin from xml layouts
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int rootWidth = displayMetrics.widthPixels-marginPadding;// maximum width on screan
if (textWidth > rootWidth) { // check if need to split the string.
int lineMax = (text.length() * rootWidth) / textWidth; // maximum Characters for each line
String result = text.replaceAll("(.{" + String.valueOf(lineMax) + "})", "$1\n"); // regex to replace each group(lineMax) of Chars with group of char + new line
textView.setText(result);
} else
textView.setText(text);
UPDATE#3: Fixed code for Listview
onCreate
ArrayList<String> data = new ArrayList<>();
data.add("000");
data.add("aaaaaaaaaaa");
data.add("aaaaaaaaaaa bbbbbbbbbbbb");
data.add("aaaaaaaaaaa bbbbbbbbbbbb cccccccccccccccc");
data.add("aaaaaaaaaaa bbbbbbbbbbbb cccccccccccccccc ddddddddddddd");
data.add("aaaaaaaaaaa bbbbbbbbbbbb cccccccccccccccc ddddddddddddd eeeeeeeeeeeee");
data.add("aaaaaaaaaaa bbbbbbbbbbbb cccccccccccccccc ddddddddddddd eeeeeeeeeeeee ffffffffffffffffff");
data.add("aaaaaaaaaaa bbbbbbbbbbbb cccccccccccccccc ddddddddddddd eeeeeeeeeeeee ffffffffffffffffff gggggggggggggggg");
data.add("aaaaaaaaaaa bbbbbbbbbbbb cccccccccccccccc ddddddddddddd eeeeeeeeeeeee ffffffffffffffffff gggggggggggggggg hhhhhhhhhhhhhhhh");
ListView listView = (ListView) findViewById(R.id.listview);
MyAdapter adapter= new MyAdapter(data,this);
listView.setAdapter(adapter);
adapter.notifyDataSetChanged();
MyAdapter.java
public class MyAdapter extends BaseAdapter {
private LayoutInflater inflater = null;
Context context;
ArrayList<String> data;
public MyAdapter(ArrayList<String> data, Context context) {
this.context = context;
this.data = data;
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return data.size();
}
#Override
public Object getItem(int i) {
return data.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(final int i, View convertView, ViewGroup viewGroup) {
final View view = inflater.inflate(R.layout.item, null);
final TextView tv_text = (TextView) view.findViewById(R.id.tvValue);
if (data.get(i) != null) {
tv_text.post(new Runnable() {
#Override
public void run() {
//TextView is Ready to be used.
fixText(data.get(i),tv_text);
}
});
}
return view;
}
private void fixText(String text, TextView textView) {
Rect bounds = new Rect();
Paint textPaint = textView.getPaint();
textPaint.getTextBounds(text, 0, text.length(), bounds);
int textWidth = bounds.width();// get text width in pixel
int marginPadding = 100;// we have some padding and margin from xml layouts
DisplayMetrics displayMetrics = new DisplayMetrics();
((MainActivity) context).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int rootWidth = textView.getWidth();//displayMetrics.widthPixels - marginPadding;// maximum width on screan
if (textWidth > rootWidth) { // check if need to split the string.
//int lineMax = (text.length() * rootWidth) / textWidth; // maximum Characters for each line
//String result = text.replaceAll("(.{" + String.valueOf(lineMax-5) + "})", "$1\n"); // regex to replace each group(lineMax) of Chars with group of char + new line
String result = wrapText(rootWidth,text);
textView.setText(result);
} else
textView.setText(text);
}
private String wrapText(int textviewWidth,String mQuestion) {
String temp = "";
String sentence = "";
String[] array = mQuestion.split(" "); // split by space
for (String word : array) {
if ((temp.length() + word.length()) < textviewWidth) { // create a temp variable and check if length with new word exceeds textview width.
temp += " "+word;
} else {
sentence += temp+"\n"; // add new line character
temp = word;
}
}
return (sentence.replaceFirst(" ", "")+temp);
}
item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="1.0"
tools:background="#color/colorAccent">
<LinearLayout
android:id="#+id/flBubble"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:background="#color/colorPrimary"
android:layout_weight="0.9">
<ImageView
android:id="#+id/ivSay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:contentDescription="default_content_description"
android:padding="8dp"
android:src="#android:drawable/ic_media_play"
android:tint="#color/colorPrimaryDark" />
<TextView
android:id="#+id/tvValue"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="8dp"
android:textColor="#000000"
android:textSize="16sp"
tools:text="I would like to go to an Italian restaurant jkjk l;'"/>
</LinearLayout>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0.1"/>
</LinearLayout>
Try this
<TextView
android:id="#+id/tvValue"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="8dp"
android:textColor="#color/black"
android:textSize="16sp"
tools:text="I would like to go to an Italian restaurant"/>
</LinearLayout>
You can try with
Autosizing TextViews
The Support Library 26.0 provides full support to the autosizing TextView feature on devices running Android versions prior to Android 8.0 (API level 26). The library provides support to Android 4.0 (API level 14) and higher. The android.support.v4.widget package contains the TextViewCompat class to access features in a backward-compatible fashion
For Example:
<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
android:autoSizeTextType="uniform" />
For more details Guidelines go HERE
Their is Library too HERE
Try this
private String getWidthFitString(String input) {
Paint paint = text.getPaint();
// you can define max width by your self
int maxWidth = getContentMaxWidth();
float width = paint.measureText(input);
if (width > maxWidth) {
List<String> words = Arrays.asList(input.split("\\s"));
int breakLinePosition = 0;
String toBreakLineText;
List<String> toBreakLineWords = new ArrayList<>();
while (breakLinePosition < words.size()) {
toBreakLineWords.add(words.get(breakLinePosition));
toBreakLineText = TextUtils.join(" ", toBreakLineWords);
float currentWidth = paint.measureText(toBreakLineText);
if (currentWidth > maxWidth) {
break;
}
breakLinePosition ++;
}
if (breakLinePosition > 1) {
toBreakLineWords.remove(toBreakLineWords.size() - 1);
toBreakLineText = TextUtils.join(" ", toBreakLineWords);
List<String> fromBreakLineWords = new ArrayList<>();
for (int i = breakLinePosition; i < words.size(); i++) {
fromBreakLineWords.add(words.get(i));
}
return toBreakLineText + "\n" + getWidthFitString(TextUtils.join(" ", fromBreakLineWords));
} else {
return input;
}
}
return input;
}
For those whose string has non-breaking space character may try the following:
value.replace("\u00A0", " ")
Hope this might help
Change your TextView to EditText and put this 2 lines. it should help you
android:inputType="textMultiLine"
android:enabled="false"
This will place you text properly and later on you can give a edit feature in your application if you need.
I have a listview with multiple row layouts (radio group, edit text, text view), with multiple choice mode. I want to retrieve it's selected data (user-selected or typed data) on a submit button.
This is the code from my main file:
public class GraduatingSurvey extends Fragment {
private static final String LOGTAG = "log" ;
public String stdcode = "024-15-16079";
Button submit;
RadioGroup radioGroup;
RadioButton radioButton;
EditText comment;
ArrayList<GraduatingSurveyModel> graduatingModelList;
ListView listView;
View view;
public GraduatingSurvey() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.fragment_graduating_survey, container, false);
submit = (Button) view.findViewById(R.id.btn_graduate_submit);
listView = (ListView) view.findViewById(R.id.graduate_list);
graduatingModelList = new ArrayList<GraduatingSurveyModel>();
//handle submit form Event.
submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final int child=listView.getAdapter().getCount();
Log.i("radio", "child: " + child);
SparseBooleanArray checked = listView.getCheckedItemPositions(); //Is returning empty
Log.i("radio", "sparseArray: " + checked);
for(int i=0;i<child;i++) {
int type = listView.getAdapter().getItemViewType(i);
Log.i("radio", "type: " + type);
if(type == 2){
// Want to retrieve data here
}
if(type == 0)
{
}
if(type == 1){
}
}
}
});
NetAsync(view);
return view;
}
This is the adapter:
public class GraduatingSurveyAdapter extends ArrayAdapter<GraduatingSurveyModel> {
private static final int TYPE_ITEM1 = 0;
private static final int TYPE_ITEM2 = 1;
private static final int TYPE_ITEM3 = 2;
int type;
ArrayList<GraduatingSurveyModel> ArrayListSurvey;
int Resource;
Context context;
LayoutInflater vi;
public GraduatingSurveyAdapter(Context context, int resource, ArrayList<GraduatingSurveyModel> objects) {
super(context, resource, objects);
ArrayListSurvey = objects;
Resource = resource;
this.context = context;
vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getItemViewType(int position) {
if (position == 14){
type = TYPE_ITEM1;
} else if (position == 23 || position == 24 || position == 25){
type = TYPE_ITEM2;
}
else
{
type= TYPE_ITEM3 ;
}
return type;
}
#Override
public int getViewTypeCount() {
return 3;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
//first Item or row is being created hence ConvertView is NULL
if(convertView == null){
if (type == TYPE_ITEM2) {
convertView = vi.inflate(R.layout.graduates_survey_comment,null);
holder = new ViewHolder();
holder.tv_question = (TextView) convertView.findViewById(R.id.graduate_question);
holder.tv_comment = (TextView) convertView.findViewById(R.id.graduate_comment);
}
else if (type == TYPE_ITEM1) {
convertView = vi.inflate(R.layout.graduates_survey_subheader,null);
holder = new ViewHolder();
holder.tv_question = (TextView) convertView.findViewById(R.id.graduate_question);
}
else {
//infalte layout of normaltype
//Inflating items only once
convertView = vi.inflate(Resource,null);
holder = new ViewHolder();
holder.tv_question = (TextView) convertView.findViewById(R.id.graduate_question);
holder.tv_comment = (TextView) convertView.findViewById(R.id.graduate_comment);
holder.rg = (RadioGroup) convertView.findViewById(R.id.graduate_radioGroup);
holder.rg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
/* RadioButton radioButton = (RadioButton) group.findViewById(checkedId);
Log.i("radio", "onCheckedChanged: " + radioButton + " " + checkedId);
notifyDataSetChanged();*/
Integer pos = (Integer) group.getTag();
GraduatingSurveyModel element = ArrayListSurvey.get(pos);
switch (checkedId) {
case R.id.graduate_sAgree:
element.current = GraduatingSurveyModel.ANSWER_ONE_SELECTED;
break;
case R.id.graduate_agree:
element.current = GraduatingSurveyModel.ANSWER_TWO_SELECTED;
break;
case R.id.graduate_uncertain:
element.current = GraduatingSurveyModel.ANSWER_THREE_SELECTED;
break;
case R.id.graduate_disagree:
element.current = GraduatingSurveyModel.ANSWER_FOUR_SELECTED;
break;
case R.id.graduate_sDisagree:
element.current = GraduatingSurveyModel.ANSWER_FIVE_SELECTED;
break;
default:
element.current = GraduatingSurveyModel.NONE; // Something was
}
}
});
}
convertView.setTag(holder);
}else{
//reuse code. (Inflate items only once then reuse them.)
holder = (ViewHolder) convertView.getTag();
}
// get info from ArrayList(that came through JSON), and set it in the View.
if (type == TYPE_ITEM1) {
holder.tv_question.setText(ArrayListSurvey.get(position).getQuestion());
}
else if (type == TYPE_ITEM2) {
holder.tv_question.setText(ArrayListSurvey.get(position).getQuestion());
}
else{
holder.rg.setTag(new Integer(position));
holder.tv_question.setText(ArrayListSurvey.get(position).getQuestion());
if(ArrayListSurvey.get(position).current != GraduatingSurveyModel.NONE){
RadioButton r = (RadioButton) holder.rg.getChildAt(ArrayListSurvey.get(position).current);
r.setChecked(true);
}else{
holder.rg.clearCheck();
}
}
return convertView;
}
static class ViewHolder{
private TextView tv_question;
private TextView tv_comment;
private LinearLayout lv_choices;
private RadioGroup rg;
}
}
This is my model:
public class GraduatingSurveyModel {
public String question;
public String comment;
public String choices;
public String subHeading;
public int current = NONE; // hold the answer picked by the user, initial is NONE(see below)
public static final int NONE = 1000; // No answer selected
public static final int ANSWER_ONE_SELECTED = 0; // first answer selected
public static final int ANSWER_TWO_SELECTED = 1; // second answer selected
public static final int ANSWER_THREE_SELECTED = 2; // third answer selected
public static final int ANSWER_FOUR_SELECTED = 3; // forth answer selected
public static final int ANSWER_FIVE_SELECTED = 4; // forth answer selected
public GraduatingSurveyModel() {
}
public String getQuestion() {
return question;
}
public void setQuestion(String question) {
this.question = question;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public String getChoices() {
return choices;
}
public void setChoices(String choices) {
this.choices = choices;
}
public String getSubHeading() {
return subHeading;
}
public void setSubHeading(String subHeading) {
this.subHeading = subHeading;
}
}
And this is the XML layout of the main fragment:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
android:background="#color/dialog_background"
android:orientation="vertical"
tools:context="iulms.iunc.edu.pk.iqraiulms.GraduatingSurvey"
android:id="#+id/main_layout">
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/graduate_list"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_above="#+id/btn_graduate_submit"
/>
<Button
android:id="#+id/btn_graduate_submit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="submit"
android:layout_alignParentBottom="true"
/>
</RelativeLayout>
These are the layouts for the different types of rows in listview
Row type 1:
<?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:background="#color/dialog_background"
android:orientation="vertical"
android:paddingBottom="16dp"
android:paddingTop="16dp">
<TextView
android:id="#+id/graduate_question"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="15dp"
android:text="1. Here comes questions?"
android:textSize="13dp" />
<!-- <EditText
android:id="#+id/graduate_comment"
style="#style/GraduateTextBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:background="#drawable/textbox"
android:ems="10"
android:hint="Comment"
android:inputType="textMultiLine"
android:lines="3" />-->
<LinearLayout
android:id="#+id/graduate_choices"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RadioGroup
android:id="#+id/graduate_radioGroup"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RadioButton
android:id="#+id/graduate_sAgree"
style="#style/GraduateRadioButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/checkbox_selector"
android:button="#android:color/transparent"
android:checked="false"
android:text="Strongly Agree" />
<RadioButton
android:id="#+id/graduate_agree"
style="#style/GraduateRadioButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/checkbox_selector"
android:button="#android:color/transparent"
android:checked="false"
android:text="Agree" />
<RadioButton
android:id="#+id/graduate_uncertain"
style="#style/GraduateRadioButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/checkbox_selector"
android:button="#android:color/transparent"
android:checked="false"
android:text="Uncertain"
/>
<RadioButton
android:id="#+id/graduate_disagree"
style="#style/GraduateRadioButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/checkbox_selector"
android:button="#android:color/transparent"
android:checked="false"
android:text="Disagree" />
<RadioButton
android:id="#+id/graduate_sDisagree"
style="#style/GraduateRadioButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/checkbox_selector"
android:button="#android:color/transparent"
android:checked="false"
android:text="Strongly Disagree" />
</RadioGroup>
</LinearLayout>
</LinearLayout>
Row type 2
<?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:background="#color/dialog_background"
android:orientation="vertical"
android:paddingBottom="16dp"
android:paddingTop="16dp">
<TextView
android:id="#+id/graduate_question"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="15dp"
android:text="1. Here comes questions?"
android:textSize="13dp" />
<EditText
android:id="#+id/graduate_comment"
style="#style/GraduateTextBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:background="#drawable/textbox"
android:ems="10"
android:hint="Comment"
android:inputType="textMultiLine"
android:lines="3" />
</LinearLayout>
Row type 3:
<?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:background="#color/dialog_background"
android:orientation="vertical"
android:paddingBottom="16dp"
android:paddingTop="16dp">
<TextView
android:id="#+id/graduate_question"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="15dp"
android:text="1. Here comes questions?"
android:textSize="15dp"
android:textColor="#color/primary_dark"/>
</LinearLayout>
How can I retrieve the data submitted in the main fragment?
Thanks
For this You can create a custom class with row values like,
Arraylist<CustomClass> mnewList = new ArrayList();
Class CustomClass
{
private String edValues,
private int rowId,
}
etc.
Then Implement on change listener for radio button in that add/remove current selected items to that custom list.
I'm having trouble thinking about how to make an automatic slideshow using ImageSwitchers and Gallery. The only thing I understand is the animation between transitioning pictures when you select them from gallery, like the way they fade or move from left to right.
EDIT
My purpose is trying to make a slideshow the same way when you create gallery and select each pictures then use imageswitcher to display the selected picture on the bottom layout. Just this time, instead actually clicking, I want the pictures to move automatically (next one after the last one), like on Powerpoints and with a timer obviously.
Here's the whole class:
package project.CaseStudy;
public class Slideshow extends Activity implements ViewFactory {
//---the images to display---
Integer[] imageIDs = {
R.drawable.pic1,
R.drawable.pic2,
R.drawable.pic3,
R.drawable.pic4,
R.drawable.pic5,
R.drawable.pic6,
R.drawable.pic7
};
TextView legend;
TextView imageID;
CheckBox repeat;
CheckBox image;
CheckBox text;
public int picture;
public int pictureCurrentlySelected;
private ImageSwitcher imageSwitcher;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.slideshow);
legend = (TextView) findViewById(R.id.legend);
imageID = (TextView) findViewById(R.id.imagenum);
repeat = (CheckBox) findViewById(R.id.repeat);
image = (CheckBox) findViewById(R.id.number);
text = (CheckBox) findViewById(R.id.text);
//text.setEnabled(true);
//image.setEnabled(true);
//repeat.setEnabled(true);
imageSwitcher = (ImageSwitcher) findViewById(R.id.switcher1);
imageSwitcher.setFactory(this);
imageSwitcher.setInAnimation(AnimationUtils.loadAnimation(this,
android.R.anim.fade_in));
imageSwitcher.setOutAnimation(AnimationUtils.loadAnimation(this,
android.R.anim.fade_out));
/*imageSwitcher.setInAnimation(AnimationUtils.loadAnimation(this,
android.R.anim.slide_in_left));
imageSwitcher.setOutAnimation(AnimationUtils.loadAnimation(this,
android.R.anim.slide_out_right));
*/
pictureCurrentlySelected = -1;
Gallery gallery = (Gallery) findViewById(R.id.gallery1);
gallery.setAdapter(new ImageAdapter(this));
gallery.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent,
View v, int position, long id)
{
imageSwitcher.setImageResource(imageIDs[position]);
picture = position;
pictureCurrentlySelected = picture;
check();
}
});
}
public View makeView()
{
ImageView imageView = new ImageView(this);
imageView.setBackgroundColor(0xFF000000);
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
imageView.setLayoutParams(new
ImageSwitcher.LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
return imageView;
}
public class ImageAdapter extends BaseAdapter
{
private Context context;
private int itemBackground;
public ImageAdapter(Context c)
{
context = c;
//---setting the style---
TypedArray a = obtainStyledAttributes(R.styleable.Gallery1);
itemBackground = a.getResourceId(
R.styleable.Gallery1_android_galleryItemBackground, 0);
a.recycle();
}
//---returns the number of images---
public int getCount()
{
return imageIDs.length;
}
//---returns the item---
public Object getItem(int position)
{
return position;
}
//---returns the ID of an item---
public long getItemId(int position)
{
return position;
}
//---returns an ImageView view---
public View getView(int position, View convertView, ViewGroup parent)
{
ImageView imageView = new ImageView(context);
imageView.setImageResource(imageIDs[position]);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setLayoutParams(new Gallery.LayoutParams(150, 120));
imageView.setBackgroundResource(itemBackground);
return imageView;
}
}
public void onCheckBoxClickListener(View v)
{
boolean checked = ((CheckBox) v).isChecked();
switch(v.getId()){
case R.id.repeat:
/*if(checked)
{
return;
}*/
break;
case R.id.text:
if(!checked)
legend.setText("");
else
{
if(pictureCurrentlySelected == -1)
{
legend.setText("");
}
else
check();
}
break;
case R.id.number:
if(!checked)
imageID.setText("");
else
{
if(pictureCurrentlySelected == -1)
{
legend.setText("");
}
else
check();
}
break;
}
}
private void check()
{
if(text.isChecked())
{
if(picture == 0)
legend.setText("This is San Fransisco's Bridge. A beautiful Sight!");
else if(picture == 1)
legend.setText("This is the train used to pick up the bitches around town.");
else if(picture == 2)
legend.setText("The outstanding lake of San Fransisco");
else if(picture == 3)
legend.setText("A beautiful view of the city!");
else if(picture == 4)
legend.setText("Beauty at its limit.");
else if(picture == 5)
legend.setText("Town at sunset.");
else
legend.setText("Bridge during within a beautiful sight.");
}
/*else
legend.setText("");*/
if(image.isChecked())
{
if(picture == 0)
imageID.setText("Image number 1");
else if(picture == 1)
imageID.setText("Image number 2");
else if(picture == 2)
imageID.setText("Image number 3");
else if(picture == 3)
imageID.setText("Image number 4");
else if(picture == 4)
imageID.setText("Image number 5");
else if(picture == 5)
imageID.setText("Image number 6");
else
imageID.setText("Image number 7");
}
//else
//legend.setText("");
if(repeat.isChecked())
{
}
//else;
}
}
Ignore the last two methods if it's too complicated to understand Im just sketching my program and will eventually fix the redundancy later.
Here's the XML layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Images of San Francisco" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<CheckBox
android:id="#+id/repeat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onCheckBoxClickListener"
android:text="Repeat" />
<CheckBox
android:id="#+id/number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onCheckBoxClickListener"
android:text="Image ID" />
<CheckBox
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onCheckBoxClickListener"
android:text="Text" />
</LinearLayout>
<Gallery
android:id="#+id/gallery1"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.50" >
<ImageSwitcher
android:id="#+id/switcher1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</ImageSwitcher>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Image number: " />
<TextView
android:id="#+id/imagenum"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="#+id/legend"
android:layout_width="match_parent"
android:layout_height="57dp"
android:text="" />
</LinearLayout>
</LinearLayout>
I'm not sure exactly what you're trying to achieve, but the best (read: easiest) way I know of to create a small slideshow is to simply put your imageViews and/or textViews into a frame layout. Then in your code, you would use a switch statement that sets the visibility of each image.
eg. case 0:
image1.setVisibility (View.VISIBLE);
image2.setVisibility (View.INVISIBLE);
Etc....