setMinimumHeight() on LinearLayout isn't working (in subclass) - java

I have a subclass of a liner layout (referenced from XML custom type) The minimum height I've tried to set just isn't working nor is setting the layout. I need to do this programatically...
Why isn't setMinimumHeight() working?
NB: The complexity of the code can be ignored, the value it is setting is 70
public class SummaryDynamicSpacer extends LinearLayout {
private static final String TAG = "mymeter-DynamicSpacer";
int dpWidth = 0;
int dpHeight = 0;
public SummaryDynamicSpacer(Context context) {
super(context);
init(context);
}
public SummaryDynamicSpacer(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context) {
DisplayMetrics metrics = new DisplayMetrics();
((Activity)context).getWindowManager().getDefaultDisplay().getMetrics(metrics);
//Set dpWidth, this is the key metric we use for scaling.
float density = getResources().getDisplayMetrics().density;
float dpWidth = metrics.widthPixels / density;
float dpHeight = metrics.heightPixels / density;
this.dpWidth = (int)dpWidth;
this.dpHeight = (int)dpHeight;
Log.d(TAG, "zyxHeightDP: "+metrics.heightPixels / density);
int id = this.getId();
int increment = 10;
int adjustment = getValueForLargeDevice(increment);
if(id == R.id.betweenAddressAndTopBox) {
doBetweenAddressAndTopBox(context, adjustment);
} else if(id == R.id.betweenTopAndAddress) {
doBetweenTopAndAddress(context, adjustment);
}
Log.d(TAG, "SettingHeight: "+adjustment);
this.setBackgroundColor(Color.BLUE);
}
private void doBetweenAddressAndTopBox(Context context, int adjustment) {
this.setMinimumHeight(adjustment);
}
private void doBetweenTopAndAddress(Context context, int adjustment) {
this.setMinimumHeight(adjustment);
}
private int getValueForLargeDevice(double increment) {
int largeDeviceAdjustment = 0;
if(dpHeight > 750) {
int difference = (int)dpHeight - 750;
int interval = 25;
int iterations = (difference / interval) > 12 ? 12 : (difference / interval);
int increasePerInterval = 0;
for(int i=0; i < iterations; i++) {
largeDeviceAdjustment += increment;
}
return largeDeviceAdjustment;
} else {
return 1;
}
}
}

I think your code is fine. Your layout likely has an issue. Did you set the layout as follows?
<com.example.dynamicspacerlayout.SummaryDynamicSpacer
android:id="#+id/betweenAddressAndTopBox"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
See this also does minHeight do anything?
GalaxyNexus Screen Shot running your code
Nexus7 Screen Shot
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<EditText
android:id="#+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Top Text">
<requestFocus />
</EditText>
<com.example.dynamicspacerlayout.SummaryDynamicSpacer
android:id="#+id/betweenAddressAndTopBox"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textColor="#android:color/white"
/>
</com.example.dynamicspacerlayout.SummaryDynamicSpacer>
<EditText
android:id="#+id/editText2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Bottom Text"
/>
</LinearLayout>
MainActivity.java
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
int minimumHeight = findViewById(R.id.betweenAddressAndTopBox).getHeight();
TextView text = (TextView) findViewById(R.id.textView1);
text.setText("Height: " + minimumHeight);
// text.setVisibility(minimumHeight > 1 ? View.VISIBLE : View.GONE);
}
}, 1000);
}
}
Hope that Helps!

Related

MP Chart in listView

Please assist me with implementing MP Line Chart in ListView; it works good in recycler view, however it loses its size as I add more than 5 items.
Because of the scroll view, I'm using an expanded listView to reduce issues, yet the chart looks like this.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_margin="10sp"
android:orientation="vertical"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="#color/black"
android:text="#string/most_active_stocks"/>
<LinearLayout
android:visibility="visible"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="center"
android:gravity="center"
android:layout_margin="10sp">
<Button
android:layout_width="wrap_content"
android:textSize="10sp"
android:layout_gravity="center"
android:layout_height="40dp"
android:layout_margin="5dp"
android:background="#drawable/virtualtrading_button"
android:text="Volume"
android:gravity="center"
android:textColor="#color/black" />
<Button
android:layout_width="wrap_content"
android:layout_height="40dp"
android:textSize="10sp"
android:layout_gravity="center"
android:layout_margin="5dp"
android:background="#drawable/virtualtrading_button"
android:text="%Turnover"
android:gravity="center"
android:textColor="#color/black" />
<Button
android:layout_width="wrap_content"
android:layout_height="40dp"
android:textSize="10sp"
android:layout_margin="5dp"
android:layout_gravity="center"
android:background="#drawable/virtualtrading_button"
android:text="Range"
android:gravity="center"
android:textColor="#color/black" />
</LinearLayout>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.catalyst.maksl.Components.ExpandableHeightListView
android:id="#+id/moverlist"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:drawSelectorOnTop="false"
android:fadingEdge="vertical"
android:divider="#android:color/transparent"
android:dividerHeight="5dp"
android:fitsSystemWindows="true"
android:listSelector="#00000000"
android:scrollbars="none"
android:smoothScrollbar="true" />
</RelativeLayout>
</LinearLayout>
ExpandableListView Class
public class ExpandableHeightListView extends ListView {
boolean expanded = false;
public ExpandableHeightListView(Context context)
{
super(context);
}
public ExpandableHeightListView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public ExpandableHeightListView(Context context, AttributeSet attrs,int defStyle)
{
super(context, attrs, defStyle);
}
public boolean isExpanded()
{
return expanded;
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
// HACK! TAKE THAT ANDROID!
if (isExpanded())
{
// Calculate entire height by providing a very large height hint.
// But do not use the highest 2 bits of this integer; those are
// reserved for the MeasureSpec mode.
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
else
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
public void setExpanded(boolean expanded)
{
this.expanded = expanded;
}
}
adapter class :
public class MostActiveStocksAdapter extends BaseAdapter {
private static LineDataSet set1;
public static Drawable drawablePositive = ContextCompat.getDrawable(Logs.globalContext, R.drawable.graph_green_bg);
public static Drawable drawable_negative = ContextCompat.getDrawable(Logs.globalContext, R.drawable.graph_bg);
Context context;
private Double changePercentage;
ArrayList<String> arrayList = new ArrayList<String>();
LayoutInflater mInflater = null;
private ViewHolder holder;
public ArrayList<Entry> values;
public LineData data;
public MostActiveStocksAdapter(Context context, ArrayList<String> arrayList) {
this.context = context;
this.arrayList = arrayList;
mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return arrayList.size();
}
#Override
public Object getItem(int position) {
return arrayList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.most_active_stocks_listitem, null);
holder = new ViewHolder();
holder.moverSymbolName = (TextView) convertView.findViewById(R.id.moversymbolName);
holder.moverScripName = (AutoResizeTextView) convertView.findViewById(R.id.moversmainSymbolName);
holder.moverLastTradePrice = (TextView) convertView.findViewById(R.id.moverslastTradePrice);
holder.moverchange = (AutoResizeTextView) convertView.findViewById(R.id.moversindexChange);
holder.moverMarket = (TextView) convertView.findViewById(R.id.moverssymbolMarket);
holder.sector = convertView.findViewById(R.id.movertextSector);
holder.nameIcon = convertView.findViewById(R.id.moverNameicon);
holder.masLineChart = convertView.findViewById(R.id.moversgraph);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
ScripBean scripBean = Logs.allScripBean.get(arrayList.get(position));
MostActiveStockMarketFeedBean marketFeedBean = Logs.mostActiveStockMarketFeedBeanHashMap.get(arrayList.get(position));
if (marketFeedBean != null) {
changePercentage = marketFeedBean.getChange() / (marketFeedBean.getLastTradePrice() - marketFeedBean.getChange()) * 100;
holder.moverScripName.setText(marketFeedBean.getScrip());
holder.moverSymbolName.setText(marketFeedBean.getScripName());
holder.sector.setText(scripBean.getSectorName());
holder.nameIcon.setText(marketFeedBean.getScrip().substring(0,1));
holder.moverLastTradePrice.setText(Logs.priceFormat.format(marketFeedBean.getLastTradePrice()).replace("-", ""));
setData(5,3);
customiseChart();
if(marketFeedBean.getChange() != 0.0) {
if (Logs.priceFormat.format(changePercentage).contains("-")) {
holder.moverLastTradePrice.setBackground(context.getResources().getDrawable(R.drawable.bg_negativecell));
}
else
{
holder.moverLastTradePrice.setBackground(context.getResources().getDrawable(R.drawable.bg_positivecell));
}
holder.moverchange.setText(marketFeedBean.getChange() + " " + "(" + Logs.priceFormat.format(changePercentage).replace("-", "") + "%)");
}
else
{
holder.moverchange.setText("(0.00%)");
}
}
else {
String sm = arrayList.get(position);
holder.moverScripName.setText(sm.split("\\:", -1)[0]);
holder.moverMarket.setText(sm.split("\\:", -1)[1]);
holder.moverSymbolName.setText("");
holder.moverLastTradePrice.setText("0.00");
holder.moverchange.setText("0.00");
}
return convertView;
}
private void setData(int count, float range) {
values = new ArrayList<>();
for (int i = 0; i < count; i++) {
float val = (float) (Math.random() * range) - 30;
values.add(new Entry(i, val));
}
set1 = new LineDataSet(values, "DataSet 1");
set1.setDrawCircles(false);
set1.setDrawFilled(true);
set1.setLineWidth(1f);
set1.setColor(Color.GREEN);
set1.setMode(LineDataSet.Mode.CUBIC_BEZIER);
set1.setDrawFilled(true);
set1.setFillDrawable(drawablePositive);
set1.setFillFormatter(new IFillFormatter() {
#Override
public float getFillLinePosition(ILineDataSet dataSet, LineDataProvider dataProvider) {
return holder.masLineChart.getAxisLeft().getAxisMinimum();
}
});
ArrayList<ILineDataSet> dataSets = new ArrayList<>();
dataSets.add(set1);
data = new LineData(dataSets);
holder.masLineChart.setData(data);
}
private void customiseChart()
{
holder.masLineChart.getDescription().setEnabled(false);
holder.masLineChart.setDrawGridBackground(false);
holder.masLineChart.setDragEnabled(false);
holder.masLineChart.getLegend().setEnabled(false);
holder.masLineChart.setScaleEnabled(true);
holder.masLineChart.setScaleYEnabled(false);
holder.masLineChart.setScaleXEnabled(true);
holder.masLineChart.setDrawGridBackground(false);
holder.masLineChart.getXAxis().setEnabled(false);
holder.masLineChart.getLineData().setDrawValues(false);
holder.masLineChart.getXAxis().setDrawGridLines(false);
holder.masLineChart.getXAxis().setDrawAxisLine(false);
holder.masLineChart.getAxisLeft().setDrawGridLines(false);
holder.masLineChart.getAxisRight().setDrawGridLines(false);
holder.masLineChart.getAxisRight().setDrawZeroLine(true);
holder.masLineChart.getAxisLeft().setDrawZeroLine(true);
holder.masLineChart.getAxisRight().setDrawLabels(false);
holder.masLineChart.getAxisLeft().setDrawLabels(false);
holder.masLineChart.getAxisLeft().setEnabled(false);
holder.masLineChart.getAxisRight().setEnabled(true);
holder.masLineChart.getAxisRight().setZeroLineColor(Color.BLACK);
holder.masLineChart.getAxisRight().setAxisLineColor(Color.BLACK);
holder.masLineChart.setMaxHighlightDistance(150);
holder.masLineChart.setViewPortOffsets(0, 0, 0, 0);
holder.masLineChart.setTouchEnabled(false);
holder.masLineChart.setPinchZoom(false);
}
private class ViewHolder {
TextView moverSymbolName;
TextView moverMarket;
AutoResizeTextView moverScripName;
TextView moverLastTradePrice;
AutoResizeTextView moverchange;
TextView sector;
TextView nameIcon;
LineChart masLineChart;
}
P.S: this ListView is in fragment.

Android Listview autoscroll makes items invisible

I have progress listview of progress items. Whenever the item is finished I checkmark it.
This Progress items are divided into Phases. Each phase can contain Steps. After all steps are done and marked with checkmark, code marks whole phase as done.
At the end what I do is just render a listview of phases and for each phase I dynamicly add another listview in it. I end up with listview with more listviews in it.
This works fine and I don't have any problems with it.
My boss asked me to create auto scroller which would follow the steps as being completed. This I implemented and was happy to see that It works.
Problem: I was happy that It works only to the point when the something little over of half is reached. Then suddenly items disapear. When I touch the list, List goes back to top and all the items are visible.
Any idea what could couse this behavior?
The code for this is quite large so I will share only the parts I think are needed.
//Adapters
public class ProcessFeedbackAdapter extends android.widget.BaseAdapter {
public static final String TAG = "ProcessFeedbackAdapter";
public Context appContext;
public ProgressOverviewData ProgressOverviewData;
public ListView Listview;
public int FirstNotCompletedIndex=0;
public void UpdateList(){
HotApplication.getHandler().post(new Runnable(){
#Override
public void run() {
notifyDataSetChanged();
}
});
}
public ProcessFeedbackAdapter(Context Context,ProgressOverviewData ProgressOverviewData,ListView listview){
this.appContext=Context;
this.ProgressOverviewData=ProgressOverviewData;
this.Listview=listview;
}
#Override
public int getCount() {
return ProgressOverviewData.Phases.size();
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
public void ScrollToCurrentlyActiveTask(int y){
int listviewBottom = Listview.getBottom();
if(listviewBottom <y*50){
Listview.scrollTo(0, listviewBottom);
}
else {
Listview.scrollTo(0,y*50);
}
Listview.computeScroll();
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
try {
Phase curItem = ProgressOverviewData.Phases.get(i);
LayoutInflater inflater = (LayoutInflater) appContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.progress_list_item, null);
ListView ChildList=view.findViewById(R.id.childrenList);
ViewGroup.LayoutParams params = ChildList.getLayoutParams();
int ListHeight=curItem.PhaseSteps.size()*50;
params.height=ListHeight;
ChildList.setLayoutParams(params);
TextView ProgressMessage = (TextView) view.findViewById(R.id.ProgressMessage);
ImageView Check = (ImageView) view.findViewById(R.id.CheckMark);
ImageView ErrorMark = (ImageView) view.findViewById(R.id.ErrorMark);
ProcessFeedbackChildrenAdapter ChilAdapter=new ProcessFeedbackChildrenAdapter(appContext,curItem.PhaseSteps);
ChildList.setAdapter(ChilAdapter);
int CheckVisibility = 0;
int ErrorVisibility=0;
if(curItem.Status.equals(AppEnums.StepResult.NotCompleted)){
CheckVisibility=View.INVISIBLE;
ErrorVisibility=View.INVISIBLE;
}
else if(curItem.Status.equals(AppEnums.StepResult.Completed)){
CheckVisibility=View.VISIBLE;
ErrorVisibility=View.INVISIBLE;
}
else if(curItem.Status.equals(AppEnums.StepResult.Failed)){
ErrorVisibility=View.VISIBLE;
CheckVisibility=View.INVISIBLE;
}
Check.setVisibility(CheckVisibility);
ErrorMark.setVisibility(ErrorVisibility);
ProgressMessage.setText(curItem.PhaseName);
return view;
} catch (Exception e) {
System.out.println("Something went wrong.");
}
return view;
}
}
class ProcessFeedbackChildrenAdapter extends android.widget.BaseAdapter {
public static final String TAG = "ProcessFeedbackChildrenAdapter";
public Context appContext;
public ArrayList<Step> Steps= new ArrayList<Step>();
public void UpdateList(){
HotApplication.getHandler().post(new Runnable(){
#Override
public void run() {
notifyDataSetChanged();
}
});
}
public ProcessFeedbackChildrenAdapter(Context Context,ArrayList<Step> Steps){
this.appContext=Context;
this.Steps=Steps;
}
#Override
public int getCount() {
return Steps.size();
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
try {
LayoutInflater inflater = (LayoutInflater) appContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.progress_list_item_children, null);
TextView ProgressMessage = (TextView) view.findViewById(R.id.ProgressMessage);
ImageView Check = (ImageView) view.findViewById(R.id.CheckMark);
ImageView ErrorMark = (ImageView) view.findViewById(R.id.ErrorMark);
Step curItem = Steps.get(i);
int CheckVisibility = 0;
int ErrorVisibility=0;
if(curItem.Status== AppEnums.StepResult.NotCompleted){
CheckVisibility=View.INVISIBLE;
ErrorVisibility=View.INVISIBLE;
}else {
if(curItem.Status== AppEnums.StepResult.Completed){
CheckVisibility=View.VISIBLE;
ErrorVisibility=View.INVISIBLE;
}
else if(curItem.Status==AppEnums.StepResult.Failed){
ErrorVisibility=View.VISIBLE;
CheckVisibility=View.INVISIBLE;
}
}
ProgressMessage.setText(curItem.StepName);
Check.setVisibility(CheckVisibility);
ErrorMark.setVisibility(ErrorVisibility);
return view;
} catch (Exception e) {
System.out.println("Something went wrong.");
}
return view;
}
}
// Main list view
<ListView
android:id="#+id/ProgressStepsContainer"
android:layout_width="0dp"
android:layout_height="267dp"
android:fastScrollEnabled="false"
android:scrollbarThumbVertical="#drawable/scrollbar_vertical_thumb"
android:verticalScrollbarPosition="left"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/ProgressErrorContainer"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/ProgressMessage">
</ListView>
// Phases list item
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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="0dp">
<ImageView
android:id="#+id/CheckMark"
android:layout_width="50dp"
android:layout_height="50dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/ic_overview_check" />
<ImageView
android:id="#+id/ErrorMark"
android:layout_width="50dp"
android:layout_height="50dp"
android:visibility="visible"
app:layout_constraintStart_toStartOf="#+id/CheckMark"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/ic_overview_error" />
<TextView
android:id="#+id/ProgressMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="TextView"
android:textAlignment="center"
android:textColor="#color/colorWhitish"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="#+id/CheckMark"
app:layout_constraintStart_toEndOf="#+id/CheckMark"
app:layout_constraintTop_toTopOf="parent" />
<ListView
android:id="#+id/childrenList"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
app:layout_constraintStart_toEndOf="#+id/CheckMark"
app:layout_constraintTop_toBottomOf="#+id/ProgressMessage" />
</androidx.constraintlayout.widget.ConstraintLayout>
// Steps (inner) list item
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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="wrap_content"
android:layout_height="50dp">
<ImageView
android:id="#+id/CheckMark"
android:layout_width="50dp"
android:layout_height="50dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/ic_overview_check" />
<ImageView
android:id="#+id/ErrorMark"
android:layout_width="50dp"
android:layout_height="50dp"
android:visibility="visible"
app:layout_constraintStart_toStartOf="#+id/CheckMark"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/ic_overview_error" />
<TextView
android:id="#+id/ProgressMessage"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:gravity="center"
android:text="TextView"
android:textAlignment="center"
android:textColor="#color/colorWhitish"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="#+id/CheckMark"
app:layout_constraintStart_toEndOf="#+id/CheckMark"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Your adapter code does not work in my phone. Only part of the child list is shown. In addition, I think your requirements are easier to implement by ExpandableListView. Therefore I followed your data structure and created the following demo codes which use ExpandableListView. You can start a new project and try it.
MainActivity.java:
public class MainActivity extends AppCompatActivity {
ProgressOverviewData sampleData;
ProcessFeedbackAdapter1 adapter;
ExpandableListView listView;
TextView textView;
int completedPhase = 0;
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sampleData = new ProgressOverviewData("Project", new ArrayList<Phase>());
textView = findViewById(R.id.ProgressMessage);
textView.setText(sampleData.projectName);
listView = findViewById(R.id.ProgressStepsContainer);
adapter = new ProcessFeedbackAdapter1(this, sampleData);
listView.setAdapter(adapter);
// Disable ExpandableListView from group collapse by override OnGroupClickListener.
listView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
#Override
public boolean onGroupClick(ExpandableListView expandableListView, View view, int i, long l) {
return true;
}
});
for (int i = 0; i < sampleData.Phases.size(); i++) listView.expandGroup(i);
Button btAddPhase = findViewById(R.id.bt_add_phase);
btAddPhase.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Phase newPhase = genNewPhase();
sampleData.Phases.add(newPhase);
adapter.notifyDataSetChanged();
listView.expandGroup(sampleData.Phases.size() - 1);
textView.setText(sampleData.projectName + " [" + completedPhase + "/" + sampleData.Phases.size() + "]");
}
});
Button btCompletedStep = findViewById(R.id.bt_completed_step);
btCompletedStep.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
boolean stepCompleted = false;
Step step;
String msg = "";
int viewPosition = 0;
for (int i = 0; i < adapter.getGroupCount(); i++) {
viewPosition++;
for (int j = 0; j < adapter.getChildrenCount(i); j++) {
viewPosition++;
if (adapter.getChild(i, j).Status == AppEnums.StepResult.NotCompleted) {
step = adapter.getChild(i, j);
step.Status = AppEnums.StepResult.Completed;
msg = step.StepName + " Completed!";
if (j == adapter.getGroup(i).PhaseSteps.size() - 1) {
adapter.getGroup(i).Status = AppEnums.StepResult.Completed;
completedPhase++;
textView.setText(sampleData.projectName + " [" + completedPhase + "/" + sampleData.Phases.size() + "]");
msg += "\n" + adapter.getGroup(i).PhaseName + " Completed!!!!!";
}
stepCompleted = true;
break;
}
}
if (stepCompleted) break;
}
if (stepCompleted) {
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "All Completed", Toast.LENGTH_LONG).show();
}
listView.smoothScrollToPositionFromTop(viewPosition - 1, 0);
adapter.notifyDataSetChanged();
}
});
}
private Phase genNewPhase() {
int phaseId = sampleData.Phases.size() + 1;
Random random = new Random();
int numberOfSteps = random.nextInt(5) + 1;
ArrayList<Step> steps = new ArrayList<>();
for (int j = 0; j < numberOfSteps; j++) {
Step step = new Step("Step " + (phaseId) + "-" + (j + 1));
steps.add(step);
}
return new Phase("Phase " + (phaseId) + " [" + steps.size() + "]", steps);
}
}
ProcessFeedbackAdapter1.java:
public class ProcessFeedbackAdapter1 extends BaseExpandableListAdapter {
public static final String TAG = "ProcessFeedbackAdapter";
public Context appContext;
public ProgressOverviewData ProgressOverviewData;
public ProcessFeedbackAdapter1(Context Context, ProgressOverviewData ProgressOverviewData) {
this.appContext = Context;
this.ProgressOverviewData = ProgressOverviewData;
}
#Override
public int getGroupCount() {
return ProgressOverviewData.Phases.size();
}
#Override
public int getChildrenCount(int i) {
return ProgressOverviewData.Phases.get(i).PhaseSteps.size();
}
#Override
public Phase getGroup(int i) {
return ProgressOverviewData.Phases.get(i);
}
#Override
public Step getChild(int i, int i1) {
return ProgressOverviewData.Phases.get(i).PhaseSteps.get(i1);
}
#Override
public long getGroupId(int i) {
return 0;
}
#Override
public long getChildId(int i, int i1) {
return 0;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
public View getGroupView(int i, boolean b, View view, ViewGroup viewGroup) {
try {
Phase curItem = getGroup(i);
LayoutInflater inflater = (LayoutInflater) appContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.progress_list_item, null);
TextView ProgressMessage = view.findViewById(R.id.ProgressMessage);
ImageView Check = view.findViewById(R.id.CheckMark);
ImageView ErrorMark = view.findViewById(R.id.ErrorMark);
int CheckVisibility = 0;
int ErrorVisibility = 0;
if (curItem.Status.equals(AppEnums.StepResult.NotCompleted)) {
CheckVisibility = View.INVISIBLE;
ErrorVisibility = View.INVISIBLE;
} else if (curItem.Status.equals(AppEnums.StepResult.Completed)) {
CheckVisibility = View.VISIBLE;
ErrorVisibility = View.INVISIBLE;
} else if (curItem.Status.equals(AppEnums.StepResult.Failed)) {
ErrorVisibility = View.VISIBLE;
CheckVisibility = View.INVISIBLE;
}
Check.setVisibility(CheckVisibility);
ErrorMark.setVisibility(ErrorVisibility);
ProgressMessage.setText(curItem.PhaseName);
} catch (Exception e) {
System.out.println("Something went wrong.");
}
return view;
}
#Override
public View getChildView(int i, int i1, boolean b, View view, ViewGroup viewGroup) {
try {
LayoutInflater inflater = (LayoutInflater) appContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.progress_list_item_children, null);
TextView ProgressMessage = view.findViewById(R.id.ProgressMessage);
ImageView Check = view.findViewById(R.id.CheckMark);
ImageView ErrorMark = view.findViewById(R.id.ErrorMark);
Step curItem = getChild(i, i1);
int CheckVisibility = 0;
int ErrorVisibility = 0;
if (curItem.Status == AppEnums.StepResult.NotCompleted) {
CheckVisibility = View.INVISIBLE;
ErrorVisibility = View.INVISIBLE;
} else {
if (curItem.Status == AppEnums.StepResult.Completed) {
CheckVisibility = View.VISIBLE;
ErrorVisibility = View.INVISIBLE;
} else if (curItem.Status == AppEnums.StepResult.Failed) {
ErrorVisibility = View.VISIBLE;
CheckVisibility = View.INVISIBLE;
}
}
ProgressMessage.setText(curItem.StepName);
Check.setVisibility(CheckVisibility);
ErrorMark.setVisibility(ErrorVisibility);
} catch (Exception e) {
System.out.println("Something went wrong.");
}
return view;
}
#Override
public boolean isChildSelectable(int i, int i1) {
return false;
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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:background="#000000"
tools:context=".MainActivity">
<TextView
android:id="#+id/ProgressMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Progress Messages:"
android:textColor="#F8F8F8"
android:textSize="20sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/bt_add_phase"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="20dp"
android:text="Add Phase"
app:layout_constraintRight_toLeftOf="#id/bt_completed_step"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="RtlSymmetry" />
<Button
android:id="#+id/bt_completed_step"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="20dp"
android:text="Completed Step"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="RtlSymmetry" />
<ImageView
android:id="#+id/ProgressErrorContainer"
android:layout_width="50dp"
android:layout_height="50dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/ProgressMessage" />
<ExpandableListView
android:id="#+id/ProgressStepsContainer"
android:layout_width="0dp"
android:layout_height="267dp"
android:background="#000033"
android:fastScrollEnabled="false"
android:verticalScrollbarPosition="left"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/ProgressErrorContainer"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/ProgressMessage" />
</androidx.constraintlayout.widget.ConstraintLayout>
progress_list_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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="0dp">
<ImageView
android:id="#+id/CheckMark"
android:layout_width="50dp"
android:layout_height="50dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#android:drawable/checkbox_on_background" />
<ImageView
android:id="#+id/ErrorMark"
android:layout_width="50dp"
android:layout_height="50dp"
android:visibility="visible"
app:layout_constraintStart_toStartOf="#+id/CheckMark"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#android:drawable/ic_delete" />
<TextView
android:id="#+id/ProgressMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:textAlignment="center"
android:textColor="#F8F8F8"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="#+id/CheckMark"
app:layout_constraintStart_toEndOf="#+id/CheckMark"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
progress_list_item_children.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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:paddingStart="50dp"
android:layout_width="wrap_content"
android:layout_height="50dp">
<ImageView
android:id="#+id/CheckMark"
android:layout_width="50dp"
android:layout_height="50dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#android:drawable/checkbox_on_background" />
<ImageView
android:id="#+id/ErrorMark"
android:layout_width="50dp"
android:layout_height="50dp"
android:visibility="visible"
app:layout_constraintStart_toStartOf="#+id/CheckMark"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#android:drawable/ic_delete" />
<TextView
android:id="#+id/ProgressMessage"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:gravity="center"
android:textAlignment="center"
android:textColor="#F8F8F8"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="#+id/CheckMark"
app:layout_constraintStart_toEndOf="#+id/CheckMark"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
For the classes that related to your data structure, you can copy from your original project.

How to edit dimension of customview in Android Studio?

I want to give custom dimension to custom view but when i open the app, it show me the image in small dimension. In the customview i put a GIF image.
The CustomGifView.java
public class CustomGifView extends View {
private InputStream gifInputStream;
private Movie gifMovie;
private int movieWidth, movieHeight;
private long movieDuration;
private long mMovieStart;
public CustomGifView(Context context) {
super(context);
init(context);
}
public CustomGifView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public CustomGifView(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context){
setFocusable(true);
gifInputStream = context.getResources()
.openRawResource(R.drawable.caricamento);
gifMovie = Movie.decodeStream(gifInputStream);
movieWidth = gifMovie.width();
movieHeight = gifMovie.height();
movieDuration = gifMovie.duration();
}
#Override
protected void onMeasure(int widthMeasureSpec,
int heightMeasureSpec) {
setMeasuredDimension(movieWidth, movieHeight);
}
public int getMovieWidth(){
return movieWidth;
}
public int getMovieHeight(){
return movieHeight;
}
public long getMovieDuration(){
return movieDuration;
}
#Override
protected void onDraw(Canvas canvas) {
long now = android.os.SystemClock.uptimeMillis();
if (mMovieStart == 0) { // first time
mMovieStart = now;
}
if (gifMovie != null) {
int dur = gifMovie.duration();
if (dur == 0) {
dur = 1000;
}
int relTime = (int)((now - mMovieStart) % dur);
gifMovie.setTime(relTime);
gifMovie.draw(canvas, 0, 0);
invalidate();
}
}
The caricamento.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:components="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#398596">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Caricamento in corso..."
android:id="#+id/textView"
android:textColor="#ffffff"
android:layout_marginBottom="37dp"
android:layout_above="#+id/textView4"
android:layout_centerHorizontal="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Tip: Lo sapevi che il QR Scanner rileva automaticamente il codice del tavolo?"
android:id="#+id/textView4"
android:layout_marginBottom="76dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginLeft="55dp" />
<com.faddex.ristorante.CustomGifView
android:layout_width="300dp"
android:layout_height="300dp"
android:id="#+id/view"
android:layout_above="#+id/textView"
android:layout_centerHorizontal="true" />
As you can see at the end i give 300dp - 300dp but when i open the activity in the smartphone it show always small dimension, even if i change to 10000dp - 10000dp

Add dots to TextView like in the receipt

I want to implement something like a product list in the receipt:
Beer ......................................... 20
Milk .......................................... 10
Cookies with jam ..................... 15
Smartphone 10GB 3GHz
1GB RAM NFC 10MPx
camera .................................. 400
Description:
Check info (Beer, Milk) I think it shoud be a TextView, which I need to fill with dots.
Money (20, 10) is another TextView which shoud be aligned to the right of ViewGroup.
Any ideas how to do this? Maybe I need inherited from TextView and override onDraw() or something?
Many thank for advices!!!
You should create THREE TextViews for each row, layed out one next to another:
TextView With product name (e.g. 'beer')
TextView with dots
TextView with number (e.g. '20')
Then put one product in one row. The Row should be relative layout where:
TextView no. 1 is aligned to left edge, with width set to wrap content
TextView no. 3 is aligneg to right edge, with width set to wrap content
TextView no. 2 is toLeftOf TV no. 3 and toRightOf TV no.1 and it should be filled with big amount of dots in XML file. this will never be changed.
This will work, since the TV no.2 will have width that will shrink and will always be fitted between product name and the price. believe me :)
I have the solution. Maybe it will help someone.
File check_info_item.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<RelativeLayout android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="#+id/txt_fake_value"
android:textSize="18dp"
android:textColor="#android:color/transparent"
android:layout_alignParentRight="true"/>
<example.com.CheckInfoTextView android:layout_height="wrap_content"
android:layout_width="match_parent"
android:id="#+id/txt_fake_info"
android:textSize="18dp"
android:textColor="#android:color/transparent"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="#id/txt_fake_value"/>
<TextView android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="#+id/txt_check_info_value"
android:text=""
android:textSize="18dp"
android:textColor="#000"
android:layout_alignParentRight="true"
android:layout_alignBottom="#id/txt_fake_info"/>
<example.com.CheckInfoTextView
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:textSize="18dp"
android:textColor="#000"
android:id="#+id/txt_check_info"
android:text=""
android:layout_alignParentLeft="true"
android:layout_toLeftOf="#id/txt_check_info_value"/>
</RelativeLayout>
</LinearLayout>
Code to fill the info fields (in the Activity):
View row = getLayoutInflater().inflate(R.layout.check_info_item, null);
//Fake fields needed to align base fields in the xml file
TextView txtFakeValue = (TextView) row.findViewById(R.id.txt_fake_value);
txtFakeValue.setText(String.valueOf(pair.second));
TextView txtFake = (TextView) row.findViewById(R.id.txt_fake_info);
txtFake.setText(pair.first);
TextView txtValue = (TextView) row.findViewById(R.id.txt_check_info_value);
txtValue.setText(String.valueOf(pair.second));
TextView txtTitle = (TextView) row.findViewById(R.id.txt_check_info);
txtTitle.setText(pair.first);
And the CheckInfoTextView:
public class CheckInfoTextView extends TextView {
public CheckInfoTextView(Context context) {
super(context);
}
public CheckInfoTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CheckInfoTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
super.onWindowFocusChanged(hasWindowFocus);
if(!hasWindowFocus) return;
int requiredDots = getRequiredDotsNumber();
if(requiredDots == 0) {
String text = getText().toString();
StringBuilder result = new StringBuilder();
result.append(text.substring(0, text.lastIndexOf(' ')));
result.append("\n");
result.append(text.substring(text.lastIndexOf(' ') + 1));
setText(result.toString());
requiredDots = getRequiredDotsNumber();
}
String dots = "";
for (int i = 0; i < requiredDots; ++i) {
dots += " .";
}
setText(getText() + dots);
}
private int getRequiredDotsNumber() {
final int width = getWidth();
final int lastLineWidth = (int) getLayout().getLineWidth(getLineCount() - 1);
final int availableWidthForDots = width - lastLineWidth;
final int widthOfOneDot = getWidthOfOneDot();
final int widthOfTwoDotsWithSpace = getWidthOfTwoDotsWithSpace();
final int widthOfSpace = widthOfTwoDotsWithSpace - (widthOfOneDot * 2);
final int widthOfDotWithSpace = widthOfSpace + widthOfOneDot;
int numberOfDots = availableWidthForDots / widthOfDotWithSpace;
return numberOfDots;
}
private int getWidthOfTwoDotsWithSpace() {
return getStringWidth(". .");
}
private int getWidthOfOneDot() {
return getStringWidth(".");
}
private int getStringWidth(String text) {
Rect dotBounds = new Rect();
getPaint().getTextBounds(text,0,text.length(),dotBounds);
return dotBounds.width();
}
}
I've changed Serg_'s CheckinfoTextView class so that it both works in the eclipse layout editor, but also adds spaces if possible, to put the page number as close to the right side as possible. I've also changed a bit how it is used.
To accomplish:
Milk...................23
Chocolate cookies......24
set the text to 'Milk 23' and 'Chocolate cookies 24' respectively
The number of spaces is rounded to nearest rather than rounded down, so it's better to put the number a little bit over to the right rather than too much to the left
public class DotAutofillTextView extends TextView {
private int availableWidthForDots;
private int widthOfSpace;
private int widthOfDotWithSpace;
public DotAutofillTextView(Context context) {
super(context);
}
public DotAutofillTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public DotAutofillTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
int width = getWidth() - getPaddingLeft() - getPaddingRight();
int lastLineWidth = (int) getLayout().getLineWidth(getLineCount() - 1);
availableWidthForDots = width - lastLineWidth;
int widthOfOneDot = getWidthOfOneDot();
int widthOfTwoDotsWithSpace = getWidthOfTwoDotsWithSpace();
widthOfSpace = widthOfTwoDotsWithSpace - (widthOfOneDot * 2);
widthOfDotWithSpace = widthOfSpace + widthOfOneDot;
int requiredDots = getRequiredDotsNumber();
if (requiredDots != 0) {
int spaces = getRequiredSpacesNumber(requiredDots);
StringBuilder result = new StringBuilder();
String text = getText().toString();
result.append(text.substring(0, text.lastIndexOf(' ')));
setText(result.toString());
StringBuilder dots = new StringBuilder();
for (int i = 0; i < requiredDots; ++i) {
dots.append(" .");
}
for (int i = 0; i < spaces; ++i) {
dots.append(" ");
}
result.append(dots.toString());
result.append(text.substring(text.lastIndexOf(' ') + 1));
setText(result.toString());
}
super.onLayout(changed, left, top, right, bottom);
}
private int getRequiredSpacesNumber(int requiredDots) {
float remain = (1f * availableWidthForDots) % (1f * widthOfDotWithSpace);
return (int) ((remain / widthOfSpace) + 0.5f);
}
private int getRequiredDotsNumber() {
if (getLayout() == null) {
return 1;
}
int numberOfDots = availableWidthForDots / widthOfDotWithSpace;
return numberOfDots;
}
private int getWidthOfTwoDotsWithSpace() {
return getStringWidth(". .");
}
private int getWidthOfOneDot() {
return getStringWidth(".");
}
private int getStringWidth(String text) {
Rect dotBounds = new Rect();
getPaint().getTextBounds(text, 0, text.length(), dotBounds);
return dotBounds.width();
}
}
If '.'(dots) is your basic requirement then you can try like this..
My suggestion, Use only I TextView to fit in Beer...10 (hitch)
try like this..
int label_len = 10;//Edit as per your requirement
String MoneyValue = "20";
TextView tv = (TextView)findViewById(your id);
tv.setText("Beer");
if(tv.getText().length() < label_len){
for(int i = tv.getText().length(); i < label_len; i++){
tv.setText(tv.getText()+".");
}
}
tv.setText(tv.getText() + MoneyValue);
This is a sample with hardcoded value, you can try to add dynamically...
Hope this helps...
Use a relative layout:
TextView View TextView
The first set the width to wrap content, and below the text view of the previous row.
The second view, set to to right of first text view, and use a background drawable with dots that repeat horizontally. Set the width to match parent.
The last view, set to right of middle view and width to wrap content and aligned to right of parent.
I've had the same problem and found this solution using ConstraintLayout:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<TextView
android:id="#+id/item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Phone"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
/>
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:text="...................................................................................................."
android:maxLines="1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="#id/item"
app:layout_constraintRight_toLeftOf="#id/price"/>
<TextView
android:id="#+id/price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="end"
android:text="100"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
You can achieve this by using layout.xml only.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:![enter image description here][2]layout_height="fill_parent">
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:weightSum="1">
<TextView android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="0.9"
android:text="Milk.................................................................................................................................." />
<TextView android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="0.1"
android:text="20" />
</LinearLayout>
</LinearLayout>
This solution will work for all the device with different resolutions.

How to zoom in/zoom out by increasing a layout or textView text size in **android**?

Here is the bellow code and in want to make a zoom in and out facilities by using the zoom in and out button form android.
public class ShowDescription extends Activity{
#Override
public void onCreate(Bundle savedInstanceState){
new LoadDetails(this).execute();
super.onCreate(savedInstanceState);
setContentView(R.layout.showdescription);
String theStory = null;
String pubDate = null;
String storyTitle = null;
String writer = null;
//String test = null;
Intent intent = getIntent();
if (intent != null) {
Bundle b = intent.getExtras();
if (b == null) {
theStory = "bad bundle?";
} else {
storyTitle =ComplexScript.UTF2ANSI(ComplexScript.swap(b.getString("title")))+"\n\n";
//pubDate=ComplexScript.UTF2ANSI(ComplexScript.swap(ComplexScript.Replace(b.getString("pubdate"))))+ "\n\n";
pubDate=ComplexScript.Replace(b.getString("pubdate"))+"\n";
writer=ComplexScript.UTF2ANSI(ComplexScript.swap(b.getString("writers")))+",\n"+ComplexScript.UTF2ANSI(ComplexScript.swap(b.getString("initial")))+"\n";
theStory =ComplexScript.UTF2ANSI(ComplexScript.swap(b.getString("description"))).replace('\n', ' ').replaceAll(" "," ").replaceAll("‘","Ô").replaceAll("’","Õ");
//+ "\n\nMore information:\n" + b.getString("link");
//test=b.getString("image");
}
} else {
theStory = "Information not found.";
}
//Bitmap bimage= getBitmapFromURL(test);
//iv.setImageBitmap(bimage);
Typeface tf = Typeface.createFromAsset(getAssets(),
"font/SutonnyMJ.ttf");
TextView story = (TextView)findViewById(R.id.storybox);
story.setText(Html.fromHtml("<h1><font color='#B10000'>"+storyTitle+"</font></h1><small>"+pubDate+"<br/>"+writer+"</small><p>"+theStory+"</p>"));
story.setTypeface(tf);
story.setLineSpacing(1,(float) 1.5);
TextView moto =(TextView)findViewById(R.id.moto);
moto.setText("msev` we‡bv`b mviv¶Y");
moto.setTypeface(tf);
Button backButton = (Button)findViewById(R.id.back);
backButton.setTypeface(tf);
TextView tv = (TextView) findViewById(R.id.footer);
tv.setTypeface(tf);
backButton.setOnClickListener(new Button.OnClickListener(){
public void onClick(View v) {
finish();
}
});
}}
And here below is the XML file
<?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:background="#FFF" android:orientation="vertical">
<ImageView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#86878A"
android:contentDescription="#string/app_name"
android:src="#drawable/logobn24"/>
<TextView android:id="#+id/moto"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#86878A"
android:textColor="#FFF"
android:gravity="center"/>
<TextView android:id="#+id/title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#86878A"/>
<ScrollView android:id="#+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#FFF"
android:orientation="vertical" >
<!-- android:textColor="#4e4e4e" -->
<ImageView android:id="#+id/img"
android:layout_width="150dp"
android:layout_height="100dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:contentDescription="#string/des"/>
<TextView android:id="#+id/storybox"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/img"
android:background="#FFFFFF"
android:paddingLeft="10dp"
android:textColor="#000"
android:textSize="18dp"
android:paddingTop="10dp"/>
</RelativeLayout>
</ScrollView>
<Button android:id="#+id/back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/back"/>
<TextView android:id="#+id/footer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#86878A"
android:gravity="center_vertical|center_horizontal"
android:text="#string/footer"
android:textColor="#FFF" android:lineSpacingMultiplier="1.3"/>
Can any one make a zoom in and zoom out facilities udder this class? or just increase or decrease the text size of Text View story? Can any one help me?
What happens if you call the methods of TextView?
public void setScaleX(float scaleX)
public void setScaleY(float scaleY)
This may help you...
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.widget.TextView;
public class ResizableTextViewW extends TextView {
private static final int INVALID_POINTER_ID = -1;
public static final String TAG = ResizableTextViewW.class.getSimpleName();
private float mLastTouchX;
private float mLastTouchY;
private int mActivePointerId = INVALID_POINTER_ID;
private ScaleGestureDetector mScaleDetector;
private float mScaleFactor = 1.f;
private int count = 0;
public float mPreviousScaleFactor = 1.f;
public ResizableTextViewW(Context context) {
this(context, null, 0);
}
public ResizableTextViewW(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ResizableTextViewW(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
// Let the ScaleGestureDetector inspect all events.
mScaleDetector.onTouchEvent(ev);
return true;
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
this.setText(String.valueOf(count));
this.setTextSize(10+count);
}
private class ScaleListener extends
ScaleGestureDetector.SimpleOnScaleGestureListener {
#Override
public boolean onScale(ScaleGestureDetector detector) {
mScaleFactor *= detector.getScaleFactor();
// Don't let the object get too small or too large.
mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 5.0f));
if (mScaleFactor > mPreviousScaleFactor) {
count = count + 1;
invalidate();
} else if (mScaleFactor < mPreviousScaleFactor) {
if (count > 0) {
count = count - 1;
invalidate();
}
}
mPreviousScaleFactor = mScaleFactor;
return true;
}
}

Categories