Claude Code ਨਾਲ Flutter UI ਇਟਰੇਸ਼ਨ ਲਈ ਇੱਕ ਪ੍ਰਯੋਗਿਕ ਲੂਪ — ਯੂਜ਼ਰ ਕਹਾਣੀਆਂ ਨੂੰ widget trees, ਸਟੇਟ, ਅਤੇ ਨੈਵੀਗੇਸ਼ਨ ਵਿੱਚ ਬਦਲੋ, ਬਦਲਾਵਾਂ ਨੋਂ ਮਾਡਿਊਲਰ ਅਤੇ ਸਮੀਖਿਆ-ਯੋਗ ਰੱਖਦੇ ਹੋਏ।

ਤੇਜ਼ Flutter UI ਕੰਮ ਅਕਸਰ ਚੰਗੀ ਸ਼ੁਰੂਆਤ ਕਰਦਾ ਹੈ। ਤੁਸੀਂ ਲੇਆਉਟ ਥੋੜ੍ਹਾ ਬਦਲਦੇ ਹੋ, ਇੱਕ ਬਟਨ ਜੋੜਦੇ ਹੋ, ਇੱਕ ਫੀਲਡ ਹਿਲਾਉਂਦੇ ਹੋ, ਅਤੇ ਸਕਰੀਨ ਜਲਦੀ ਬਿਹਤਰ ਹੋ ਜਾਂਦੀ ਹੈ। ਸਮੱਸਿਆ ਉਹੀਨਾਂ ਰਾਊਂਡਾਂ ਦੇ ਬਾਅਦ ਆਉਂਦੀ ਹੈ, ਜਦੋਂ ਤੇਜ਼ੀ ਬਦਲਾਵਾਂ ਦੀ ਇੱਕ ਢੇਰ ਬਣ ਜਾਂਦੀ ਹੈ ਜਿਸਨੂੰ ਕੋਈ ਵੇਖਣਾ ਨਹੀਂ ਚਾਹੁੰਦਾ।
ਟੀਆਂ ਅਕਸਰ ਇੱਕ ਹੀ ਤਰ੍ਹਾਂ ਦੀਆਂ ਗਲਤੀਆਂ ਚੁੱਕਦੇ ਹਨ:
ਇੱਕ ਵੱਡਾ ਕਾਰਨ "ਇੱਕ ਵੱਡਾ ਪ੍ਰਾਂਪਟ" ਪਹੁੰਚ ਹੈ: ਪੂਰੀ ਫੀਚਰ ਦੀ ਵਰਣਨਾ ਕਰੋ, ਸਾਰੇ ਸਕਰੀਨ ਮੰਗੋ, ਅਤੇ ਵੱਡਾ ਆਉਟਪੁੱਟ ਕਬੂਲ ਕਰੋ। ਸਹਾਇਕ ਮੱਦਦ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰਦਾ ਹੈ, ਪਰ ਇਹ ਬਹੁਤ ਸਾਰਿਆਂ ਹਿੱਸਿਆਂ ਨੂੰ ਇੱਕ ਵਾਰ ਵਿੱਚ ਛੂਹਦਾ ਹੈ। ਇਸ ਨਾਲ ਬਦਲਾਵ ਗੰਦੇ, ਸਮੀਖਿਆ-ਲਾਇਕ ਨਹੀਂ ਰਹਿ ਜਾਂਦੇ ਅਤੇ ਮਰਜ ਕਰਨਾ ਖਤਰਨਾਕ ਹੋ ਸਕਦਾ ਹੈ।
ਇੱਕ ਦੁਹਰਾਉਣਯੋਗ ਲੂਪ ਇਸਨੂੰ ਠੀਕ ਕਰਦਾ ਹੈ ਕਿਉਂਕਿ ਇਹ ਸਪਸ਼ਟਤਾ ਮਜ਼ਬੂਤ ਕਰਦਾ ਹੈ ਅਤੇ ਪ੍ਰਭਾਵਖੇਤਰ ਨੂੰ ਸੀਮਤ ਰੱਖਦਾ ਹੈ। "ਫੀਚਰ ਬਣਾਓ" ਦੀ ਬਜਾਏ, ਇਹ ਕੱਰੋ: ਇੱਕ ਯੂਜ਼ਰ ਕਹਾਣੀ ਚੁਣੋ, ਉਹ ਸਾਬਤ ਕਰਨ ਲਈ ਸਭ ਤੋਂ ਛੋਟੀ UI ਸਲਾਈਸ ਬਣਾਓ, ਉਸ ਸਲੇਸ ਲਈ ਹੀ ਲੋੜੀਂਦਾ ਸਟੇਟ ਸ਼ਾਮਲ ਕਰੋ, ਫਿਰ ਇੱਕ ਰਸਤੇ ਲਈ ਨੈਵੀਗੇਸ਼ਨ ਵਾਇਰ ਕਰੋ। ਹਰ ਪਾਸ ਕਾਫ਼ੀ ਛੋਟਾ ਰਹੇ ਤਾਂ ਸਮੀਖਿਆ ਆਸਾਨ ਹੋਵੇਗੀ ਅਤੇ ਗਲਤੀਆਂ ਨੂੰ ਵਾਪਸ ਘੁਮਾਉਣਾ ਸੌਖਾ ਹੋਵੇਗਾ।
ਮਕਸਦ ਇੱਥੇ ਇਹ ਹੈ ਕਿ ਯੂਜ਼ਰ ਕਹਾਣੀਆਂ ਨੂੰ konkreਟ ਸਕਰੀਨ, ਸਟੇਟ ਹੈਂਡਲਿੰਗ ਅਤੇ ਨੈਵੀਗੇਸ਼ਨ ਫਲੋ ਵਿੱਚ ਬਦਲਿਆ ਜਾਵੇ ਬਿਨਾਂ ਨਿਯੰਤਰਣ ਖੋਏ। ਚੰਗੇ ਤਰੀਕੇ ਨਾਲ, ਤੁਸੀਂ ਮਾਡਿਊਲਰ UI ਹਿੱਸੇ, ਛੋਟੇ ਡਿਫ਼, ਅਤੇ ਘੱਟ ਹੈਰਾਨੀਆਂ ਪ੍ਰਾਪਤ ਕਰਦੇ ਹੋ।
ਯੂਜ਼ਰ ਕਹਾਣੀਆਂ ਮਨੁੱਖਾਂ ਲਈ ਲਿਖੀਆਂ ਜਾਂਦੀਆਂ ਹਨ, widget tree ਲਈ ਨਹੀਂ। ਕੁਝ ਵੀ ਜਨਰੇਟ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ, ਕਹਾਣੀ ਨੂੰ ਇੱਕ ਛੋਟੇ UI ਸਪੇਕ ਵਿੱਚ ਤਬਦੀਲ ਕਰੋ ਜੋ ਦਿੱਖਵੀਂ ਵਿਵਹਾਰ ਨੂੰ ਵੇਰਵਾ ਕਰੇ। "ਹੋ ਗਿਆ" ਜਾਂਚਯੋਗ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ: ਜੋ ਉਪਭੋਗਤਾ ਦੇਖ ਸਕਦਾ ਹੈ, ਟੈਪ ਕਰ ਸਕਦਾ ਹੈ, ਅਤੇ ਪੁਸ਼ਟੀ ਕਰ ਸਕਦਾ ਹੈ, ਨਾ ਕਿ ਇਹ ਕਿ ਡਿਜ਼ਾਇਨ "ਆਧੁਨਿਕ ਮਹਿਸੂਸ ਹੁੰਦਾ ਹੈ।"
ਪ੍ਰਾਪਤੀਯੋਗ ਸਕੋਪ ਰੱਖਣ ਦਾ ਇਕ ਸਧਾਰਨ ਤਰੀਕਾ ਹੈ ਕਹਾਣੀ ਨੂੰ ਚਾਰ ਬਕੇਟਾਂ ਵਿੱਚ ਵੰਡਣਾ:
ਜੇ ਕਹਾਣੀ ਅਜੇ ਵੀ ਧੁੰਦਲੀ ਮਹਿਸੂਸ ਹੁੰਦੀ ਹੈ, ਤਾਂ ਸਧਾਰਨ ਭਾਸ਼ਾ ਵਿੱਚ ਇਹ ਸਵਾਲ ਜਵਾਬ ਦਿਓ:
ਸ਼ੁਰੂ ਵਿੱਚ ਪਾਬੰਦੀਆਂ ਜੋੜੋ ਕਿਉਂਕਿ ਉਹ ਹਰ ਲੇਆਉਟ ਚੋਣ ਨੂੰ ਮਾਰਗਦਰਸ਼ਨ ਦੇਂਦੀਆਂ ਹਨ: ਥੀਮ ਮੂਲ (ਰੰਗ, ਸਪੇਸਿੰਗ, ਟਾਇਪੋਗ੍ਰਾਫੀ), ਰਿਸਪਾਨਸਿਵਨੈਸ (ਪਹਿਲਾਂ ਫੋਨ portrait, ਫਿਰ ਟੈਬਲਟ), ਅਤੇ accessibility ਘੱਟੋ-ਘੱਟ (ਟੈਪ ਟਾਰਗੇਟ ਘੱਟੋ-ਘੱਟ ਆਕਾਰ, ਪਾਠ ਸਕੇਲਿੰਗ, ਅਤੇ ਚਿੰਨ੍ਹਾਂ ਲਈ ਮੈਨੀੰਗਫੁਲ ਲੇਬਲ)।
ਆਖਿਰਕਾਰ, ਇਹ ਫੈਸਲਾ ਕਰੋ ਕਿ ਕੀ ਸਥਿਰ ਹੈ ਅਤੇ ਕੀ ਲਚਕੀਲਾ ਹੈ ਤਾਂ ਕਿ ਤੁਸੀਂ ਕੋਡਬੇਸ 'ਚ churn ਨਾ ਕਰੋ। ਸਥਿਰ ਆਈਟਮ ਉਹ ਹਨ ਜਿਨ੍ਹਾਂ 'ਤੇ ਹੋਰ ਫੀਚਰ ਨਿਰਭਰ ਕਰਦੇ ਹਨ, ਜਿਵੇਂ ਰੂਟ ਨਾਂ, ਡੇਟਾ ਮਾਡਲ, ਅਤੇ ਮੌਜੂਦਾ APIs। ਲਚਕੀਲੇ ਆਈਟਮ ਉਹ ਹਨ ਜੋ ਇਤਰੈਸ਼ਨ ਲਈ ਸੁਰੱਖਿਅਤ ਹਨ, ਜਿਵੇਂ ਲੇਆਉਟ ਬਣਤਰ, ਮਾਈਕ੍ਰੋਕਾਪੀ, ਅਤੇ ਵਿਸ਼ੇਸ਼ widget ਰਚਨਾ।
ਉਦਾਹਰਨ: "ਇੱਕ ਯੂਜ਼ਰ ਵਜੋਂ, ਮੈਂ ਡੀਟੇਲ ਸਕਰੀਨ ਤੋਂ ਇੱਕ ਆਈਟਮ ਨੂੰ ਫੈਵਰਿਟਸ ਵਿੱਚ ਸੇਵ ਕਰ ਸਕਦਾ ਹਾਂ।" ਇਕ ਬਣਾਉਣਯੋਗ UI ਸਪੇਕ ਹੋ ਸਕਦੀ ਹੈ:
ਏਨਾ ਹੀ ਕਾਫੀ ਹੈ ਬਣਾਉਣ, ਸਮੀਖਿਆ ਕਰਨ ਅਤੇ ਇਟਰੇਟ ਕਰਨ ਲਈ ਬਿਨਾਂ ਅਨੁਮਾਨ ਲਗਾਉਣ ਦੇ।
ਛੋਟੇ ਡਿਫ਼ ਦੇਣਾ ਮਤਲਬ ਧੀਮੇ ਕੰਮ ਕਰਨਾ ਨਹੀਂ। ਇਹ ਹਰ UI ਬਦਲਾਅ ਨੂੰ ਸਮੀਖਿਆਯੋਗ, ਵਾਪਸ ਕਰਨਯੋਗ, ਅਤੇ ਤੋੜਨ-ਮੁਸ਼ਕਲ ਬਣਾਉਂਦਾ ਹੈ। ਸਭ ਤੋਂ ਸਧਾਰਨ ਨਿਯਮ: ਹਰ iteration ਵਿੱਚ ਇੱਕ ਸਕਰੀਨ ਜਾਂ ਇੱਕ ਇੰਟਰਐਕਸ਼ਨ।
ਸ਼ੁਰੂ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਇੱਕ ਤੰਗ ਸਲਾਈਸ ਚੁਣੋ। "Orders ਸਕਰੀਨ 'ਤੇ ਇੱਕ ਖਾਲੀ ਸਟੇਟ ਜੋੜੋ" ਚੰਗੀ ਸਲਾਈਸ ਹੈ। "ਸਾਰੇ Orders ਫਲੋ ਨੂੰ ਦੁਬਾਰਾ ਬਣਾਓ" ਨਹੀ। ਇਕ ਡਿਫ਼ ਮਨੁੱਖੀ ਸਰੋਕਾਰ ਨੂੰ ਇੱਕ ਮਿੰਟ ਵਿੱਚ ਸਮਝ ਆ ਸਕਦਾ ਹੋਵੇ, ਉਸੇ ਨਿਸ਼ਾਨੇ ਤੇ ਰਹੋ।
ਇੱਕ ਸਥਿਰ ਫੋਲਡਰ ਰਚਨਾ ਵੀ ਤੁਹਾਨੂੰ ਬਦਲਾਵ ਨੂੰ ਇੱਕਜ਼ੁਟ ਰੱਖਣ ਵਿੱਚ ਮਦਦ ਕਰਦੀ ਹੈ। ਇੱਕ ਸਧਾਰਨ, ਫੀਚਰ-ਪਹਿਲਾਂ ਲੇਆਊਟ ਤੁਹਾਨੂੰ widgets ਅਤੇ routes ਨੂੰ ਐਪ ਵਿੱਚ ਫੈਲਣ ਤੋਂ ਰੋਕਦੀ ਹੈ:
lib/
features/
orders/
screens/
widgets/
state/
routes.dart
widgets ਨੂੰ ਛੋਟਾ ਅਤੇ ਰਚਨਾਤਮਕ ਰੱਖੋ। ਜਦੋਂ ਇੱਕ widget ਦਾ ਸਾਫ਼ ਇਨਪੁਟ ਅਤੇ ਆਉਟਪੁੱਟ ਹੁੰਦਾ ਹੈ, ਤੁਸੀਂ ਲੇਆਉਟ ਬਦਲ ਸਕਦੇ ਹੋ ਬਿਨਾਂ ਸਟੇਟ ਲਾਜਿਕ 'ਤੇ ਛੇੜਛਾੜ ਕੀਤੇ, ਅਤੇ ਸਟੇਟ ਬਦਲ ਸਕਦੇ ਹੋ ਬਿਨਾਂ UI ਨੂੰ ਦੁਬਾਰਾ ਲਿਖਣ ਦੇ। ਉਹ widgets ਪਸੰਦ ਕਰੋ ਜੋ ਸਧਾਰਨ ਮੁੱਲ ਅਤੇ callbacks ਲੈਂਦੇ ਹਨ, ਨਾ ਕਿ ਗਲੋਬਲ ਸਟੇਟ।
ਇੱਕ ਲੂਪ ਜੋ ਸਮੀਖਿਆਯੋਗ ਰਹਿੰਦਾ ਹੈ:
ਇੱਕ ਕਠੋਰ ਨਿਯਮ ਰੱਖੋ: ਹਰ ਬਦਲਾਅ ਅਸਾਨੀ ਨਾਲ ਰਿਵਰਟ ਜਾਂ ਅਲਗ ਕੀਤਾ ਜਾ ਸਕੇ। ਇਟਰੇਸ਼ਨ ਦੌਰਾਨ drive-by refactors ਤੋਂ ਬਚੋ। ਜੇ ਤੁਸੀਂ ਫਿਲਹਾਲ ਅਣਸੰਬੰਧਤ ਸਮੱਸਿਆਵੇਂ ਵੇਖਦੇ ਹੋ, ਉਹ ਲਿਖੋ ਅਤੇ ਉਨ੍ਹਾਂ ਨੂੰ ਵੱਖਰੇ commit ਵਿੱਚ ਠੀਕ ਕਰੋ।
ਜੇ ਤੁਹਾਡਾ ਟੂਲ ਸਨੈਪਸ਼ਾਟ ਅਤੇ ਰੋਲਬੈਕ ਨੂੰ ਸਹਾਇਤਾ ਦਿੰਦਾ ਹੈ, ਤਾਂ ਹਰ ਸਲੇਸ ਨੂੰ ਇੱਕ ਸਨੈਪਸ਼ਾਟ ਪੌਇੰਟ ਵਜੋਂ ਵਰਤੋ। ਕੁਝ vibe-coding ਪਲੇਟਫਾਰਮ ਜਿਵੇਂ Koder.ai ਸਨੈਪਸ਼ਾਟ ਅਤੇ ਰੋਲਬੈਕ ਸ਼ਾਮਲ ਕਰਦੇ ਹਨ, ਜੋ ਵਿਸ਼ਾਲ UI ਬਦਲਾਵਾਂ ਵੇਲੇ ਅਨੁਭਵ ਸੁਰੱਖਿਅਤ ਬਣਾ ਸਕਦੇ ਹਨ।
ਇਕ ਹੋਰ ਆਦਤ ਜੋ ਸ਼ੁਰੂਆਤੀ iterations ਨੂੰ ਸ਼ਾਂਤ ਰੱਖਦੀ ਹੈ: ਸਾਂਝੇ widgets ਨੂੰ ਸੋਧਣ ਦੀ ਬਜਾਏ ਨਵੇਂ widgets ਜੋੜੋ। ਸਾਂਝੇ ਕੰਪੋਨੈਂਟਾਂ 'ਤੇ ਛੋਟਾ ਬਦਲਾਅ ਵੱਡੇ ਡਿਫ਼ ਬਣਾਉਂਦੇ ਹਨ।
ਤੇਜ਼ UI ਕੰਮ ਸੁਰੱਖਿਅਤ ਰਹਿ ਜਾਂਦਾ ਹੈ ਜਦੋਂ ਤੁਸੀਂ ਸੋਚਣ ਨੂੰ ਟਾਈਪਿੰਗ ਤੋਂ ਵੱਖ ਕਰ ਦਿੰਦੇ ਹੋ। ਕੋਡ ਜਨਰੇਟ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਇੱਕ ਸਪਸ਼ਟ widget tree ਯੋਜਨਾ ਲਵੋ।
ਸਿਰਫ਼ widget tree ਦਾ ਆਉਟਲਾਈਨ ਮੰਗੋ। ਤੁਸੀਂ widget ਨਾਮ, ਹੀਰਾਰਕੀ, ਅਤੇ ਹਰ ਹਿੱਸੇ ਵਿੱਚ ਕੀ ਦਿਖਦਾ ਹੈ ਉਹ ਚਾਹੁੰਦੇ ਹੋ। ਹੁਣ ਕੋਈ ਕੋਡ ਨਹੀਂ। ਇਹ ਉਹ ਦਰ ਹੈ ਜਿੱਥੇ ਤੁਸੀਂ ਘਟ ਰਹੀਆਂ ਸਟੇਟਾਂ, ਖਾਲੀ ਸਕਰੀਨਾਂ, ਅਤੇ ਅਣਜਾਣ ਲੇਆਉਟ ਚੋਣਾਂ ਨੂੰ ਸਸਤੇ ਵਿੱਚ ਫੜ ਸਕਦੇ ਹੋ।
ਇੱਕ ਕੰਪੋਨੈਂਟ ਬ੍ਰੇਕਡਾਊਨ ਮੰਗੋ ਜਿਸ ਵਿੱਚ ਜ਼ਿੰਮੇਵਾਰੀਆਂ ਦੱਸੋ। ਹਰ widget ਫੋਕਸਡ ਰਹੇ: ਇੱਕ widget ਹੈਡਰ ਰੇਂਡਰ ਕਰੇ, ਦੂਜਾ ਲਿਸਟ, ਤੀਜਾ ਖਾਲੀ/ਏਰਰ UI। ਜੇ ਕੁਝ ਨੂੰ ਬਾਅਦ ਵਿੱਚ ਸਟੇਟ ਦੀ ਲੋੜ ਹੋਵੇ, ਹੁਣ ਨੋਟ ਕਰੋ ਪਰ ਤੁਰੰਤ ਲਾਗੂ ਨਾ ਕਰੋ।
ਸਕਰੀਨ scaffold ਅਤੇ stateless widgets ਜਨਰੇਟ ਕਰੋ। ਇੱਕ ਸਿੰਗਲ ਸਕਰੀਨ ਫਾਈਲ ਨਾਲ ਸ਼ੁਰੂ ਕਰੋ ਜਿਸ ਵਿੱਚ placeholder ਸਮੱਗਰੀ ਅਤੇ ਸਪਸ਼ਟ TODOs ਹੋਣ। ਇਨਪੁਟ ਸਪਸ਼ਟ ਰੱਖੋ (constructor params) ਤਾਂ ਜੋ ਤੁਸੀਂ ਅਸਲੀ ਸਟੇਟ ਬਾਅਦ ਵਿੱਚ ਪਲਗ ਕਰ ਸਕੋ ਬਿਨਾਂ ਟਰੀ ਨੂੰ ਦੁਬਾਰਾ ਲਿਖਣ ਦੇ।
ਸਟਾਈਲਿੰਗ ਅਤੇ ਲੇਆਉਟ ਵੇਰਵਿਆਂ ਲਈ ਵੱਖਰਾ ਪਾਸ ਕਰੋ: ਸਪੇਸਿੰਗ, ਟਾਇਪੋਗ੍ਰਾਫੀ, ਥੀਮਿੰਗ, ਅਤੇ ਰਿਸਪਾਂਸਿਵ ਵਿਹਾਰ। ਸਟਾਈਲਿੰਗ ਨੂੰ ਆਪਣਾ ਡਿਫ਼ ਬਣਾਓ ਤਾਂ ਕਿ ਸਮੀਖਿਆ ਸਾਧਾਰਣ ਰਹੇ।
ਸੀਮਾਵਾਂ ਅੱਗੇ ਰੱਖੋ ਤਾਂ ਕਿ ਸਹਾਇਕ ਅਣਜਾਣ UI ਨਾ ਬਣਾਵੇ ਜੋ ਤੁਸੀਂ ਸ਼ਿਪ ਨਹੀਂ ਕਰ ਸਕਦੇ:
ਕਾਂਕਰੀਟ ਉਦਾਹਰਨ: ਯੂਜ਼ਰ ਕਹਾਣੀ ਹੈ "As a user, I can review my saved items and remove one." widget tree ਮੰਗੋ ਜਿਸ ਵਿੱਚ app bar, ਲਿਸਟ ਜਿਸ ਵਿੱਚ ਆਈਟਮ ਰੋਜ਼, ਅਤੇ ਇੱਕ empty state ਸ਼ਾਮਲ ਹੋਵੇ। ਫਿਰ ਇੱਕ ਬ੍ਰੇਕਡਾਊਨ ਮੰਗੋ ਜਿਵੇਂ SavedItemsScreen, SavedItemTile, EmptySavedItems। ਪਹਿਲਾਂ ਸਿਰਫ scaffold stateless widgets ਬਣਾਓ ਅਤੇ fake data ਨਾਲ ਟੈਸਟ ਕਰੋ, ਫਿਰ ਅਲੱਗ ਪਾਸ ਵਿੱਚ ਸਟਾਈਲ ਜੋੜੋ (divider, padding, ਅਤੇ ਇੱਕ ਸਾਫ਼ remove button)।
UI ਇਟਰੇਸ਼ਨ ਤਬਾਹ ਹੋ ਜਾਂਦਾ ਹੈ ਜਦੋਂ ਹਰ widget ਫੈਸਲੇ ਕਰਨਾ ਸ਼ੁਰੂ ਕਰ ਦਿੰਦਾ ਹੈ। widget tree ਨੂੰ "dumb" ਰੱਖੋ: ਇਹ ਸਟੇਟ ਪੜ੍ਹੇ ਅਤੇ ਰੇਂਡਰ ਕਰੇ, ਕਾਰੋਬਾਰੀ ਨਿਯਮ ਨਾ ਰੱਖੇ।
ਸਭ ਤੋਂ ਪਹਿਲਾਂ ਸਟੇਟਾਂ ਨੂੰ ਸਧਾਰਨ ਭਾਸ਼ਾ ਵਿੱਚ ਨਾਮ ਦਿਓ। ਜ਼ਿਆਦਾਤਰ ਫੀਚਰਾਂ ਨੂੰ "ਲੋਡਿੰਗ" ਅਤੇ "ਡਨ" ਤੋਂ ਵੱਧ ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ:
ਫਿਰ ਉਹ ਇਵੇਂਟਾਂ ਲਿਸਟ ਕਰੋ ਜੋ ਸਟੇਟ ਬਦਲ ਸਕਦੀਆਂ ਹਨ: ਟੈਪ, ਫਾਰਮ submit, pull-to-refresh, back navigation, retry, ਅਤੇ "ਉਪਭੋਗਤਾ ਨੇ ਫੀਲਡ ਸੋਧਿਆ"। ਇਹ ਅਗਾਂਹ ਵਿਚ ਅਨੁਮਾਨ ਭਰਣ ਤੋਂ ਰੋਕਦਾ ਹੈ।
ਫੀਚਰ ਲਈ ਇੱਕ ਸਟੇਟ ਪਹੁੰਚ ਚੁਣੋ ਅਤੇ ਉਸ 'ਤੇ ਟਿਕੇ ਰਹੋ। ਮਕਸਦ "ਸਭ ਤੋਂ ਵਧੀਆ ਪੈਟਰਨ" ਨਹੀਂ, ਬਲਕਿ ਸਾਵਧਾਨੀ ਨਾਲ ਸਮੀਖਿਆਯੋਗ ਡਿਫ਼ ਹਨ।
ਛੋਟੇ ਸਕਰੀਨ ਲਈ, ਇੱਕ ਸਧਾਰਨ controller (ਜਿਵੇਂ ChangeNotifier ਜਾਂ ValueNotifier) ਕਾਫੀ ਹੁੰਦਾ ਹੈ। ਲਾਜਿਕ ਨੂੰ ਇੱਕ ਥਾਂ ਰੱਖੋ:
ਕੋਡ ਜੋੜਣ ਤੋਂ ਪਹਿਲਾਂ ਸਟੇਟ ਟ੍ਰਾਂਜ਼ਿਸ਼ਨ ਸਧਾਰਨ ਇੰਗਲਿਸ਼ ਵਿੱਚ ਲਿਖੋ। ਲੌਗਇਨ ਸਕਰੀਨ ਲਈ ਉਦਾਹਰਨ:
"When the user taps Sign in: set Loading. If the email is invalid: stay in Partial input and show an inline message. If the password is wrong: set Error with a message and enable Retry. If success: set Success and navigate to Home."
ਫਿਰ ਉਹਨਾਂ ਵਾਕਾਂਉਂ ਅਨੁਸਾਰ ਘੱਟੋ-ਘੱਟ Dart ਕੋਡ ਜਨਰੇਟ ਕਰੋ। ਸਮੀਖਿਆ ਆਸਾਨ ਰਹਿੰਦੀ ਹੈ ਕਿਉਂਕਿ ਤੁਸੀਂ diff ਨੂੰ ਨਿਯਮਾਂ ਨਾਲ ਤੁਲਨਾ ਕਰ ਸਕਦੇ ਹੋ।
ਵੈਧਤਾ ਨੂੰ ਸਪਸ਼ਟ ਬਣਾਓ। ਇਹ ਫੈਸਲਾ ਕਰੋ ਕਿ ਗਲਤ ਇਨਪੁਟ ਕਿਹੜੇ ਰਵੱਈਏ ਨੂੰ ਜਨਮ ਦੇਣਗੇ:
ਜਦੋਂ ਇਹ ਉੱਤਰ ਲਿਖੇ ਹੋਏ ਹੁੰਦੇ ਹਨ, ਤੁਹਾਡੀ UI ਸਾਫ਼ ਰਹਿੰਦੀ ਹੈ ਅਤੇ ਸਟੇਟ ਕੋਡ ਛੋਟਾ ਰਹਿੰਦਾ ਹੈ।
ਚੰਗੀ ਨੈਵੀਗੇਸ਼ਨ ਇੱਕ ਛੋਟੇ ਨਕਸ਼ੇ ਵਜੋਂ ਸ਼ੁਰੂ ਹੁੰਦੀ ਹੈ, ਨਾ ਕਿ ਰੂਟਾਂ ਦੇ ਡੱਬੇ ਵਜੋਂ। ਹਰੇਕ ਯੂਜ਼ਰ ਕਹਾਣੀ ਲਈ ਚਾਰ ਲਮਹੇ ਲਿਖੋ: ਉੱਥੇ ਉਪਭੋਗੀ ਕਿੱਥੋਂ ਦਾਖਲ ਹੁੰਦਾ ਹੈ, ਅਗਲਾ ਸਭ ਤੋਂ ਸੰਭਾਵਿਤ ਕਦਮ ਕੀ ਹੈ, ਉਹ ਕਿਵੇਂ ਰੱਦ ਕਰਦਾ ਹੈ, ਅਤੇ "ਬੈਕ" ਦਾ ਕੀ ਮਤਲਬ ਹੈ (ਪਿਛਲੀ ਸਕਰੀਨ ਤੇ ਵਾਪਸ ਜਾਂ ਸੁਰੱਖਿਅਤ ਹੋਮ ਸਥਿਤੀ)।
ਇੱਕ ਸਧਾਰਨ ਰੂਟ ਮੈਪ ਉਹ ਸਵਾਲ ਜਵਾਬ ਦੇਣ ਚਾਹੀਦਾ ਹੈ ਜੋ ਆਮ ਤੌਰ ਤੇ ਦੁਬਾਰਾ ਕੰਮ ਕਰਨ ਦਾ ਕਾਰਨ ਬਣਦੇ ਹਨ:
ਫਿਰ ਸਕਰੀਨਾਂ ਵਿਚੋਂ ਲੰਮੇ ਸੰਦੇਸ਼ ('parameters') ਤੈਅ ਕਰੋ। ਸਪਸ਼ਟ ਹੋਵੋ: IDs (productId, orderId), filters (date range, status), ਅਤੇ draft data (ਅਧੂਰਾ ਫਾਰਮ)। ਜੇ ਤੁਸੀ ਇਹ ਛੱਡ ਦਿੰਦੇ ਹੋ, ਤਾਂ ਤੁਸੀਂ ਗਲੋਬਲ ਸਿੰਗਲਟਨਾਂ ਵਿੱਚ ਸਟੇਟ ਭਰ ਕੇ ਜਾਂ ਸਕਰੀਨਾਂ ਨੂੰ ਮੁੜ-ਤਿਆਰ ਕਰਕੇ ਸੰਦਰਭ ਲੱਭਣ ਲਈ ਮਜਬੂਰ ਹੋ ਜਾਵੋਗੇ।
Deep links ਮਹੱਤਵਪੂਰਕ ਹਨ ਚਾਹੇ ਤੁਸੀਂ ਇਹ ਪਹਿਲੇ ਦਿਨ ਨਹੀ ਸ਼ਿਪ ਕਰੋ। ਫੈਸਲਾ ਕਰੋ ਕਿ ਜਦੋਂ ਉਪਭੋਗੀ ਮੱਧ-ਫਲੋ 'ਤੇ ਆਉਂਦਾ ਹੈ ਤਾਂ ਕੀ ਹੋਵੇ: ਕੀ ਤੁਸੀਂ ਮਿਸਿੰਗ ਡੇਟਾ ਲੋਡ ਕਰ ਸਕਦੇ ਹੋ, ਜਾਂ ਤੁਹਾਨੂੰ ਸੁਰੱਖਿਅਤ ਐਂਟਰੀ ਸਕਰੀਨ ਤੇ ਰੀਡਾਇਰੈਕਟ ਕਰਨਾ ਚਾਹੀਦਾ ਹੈ?
ਇਸਦੇ ਨਾਲ ਇਹ ਵੀ ਫੈਸਲਾ ਕਰੋ ਕਿ ਕਿਹੜੀਆਂ ਸਕਰੀਨਾਂ ਨਤੀਜੇ ਵਾਪਸ ਕਰਨੀਆਂ ਹਨ। ਉਦਾਹਰਨ: "Select Address" ਸਕਰੀਨ addressId ਵਾਪਸ ਕਰਦੀ ਹੈ, ਅਤੇ checkout ਸਕਰੀਨ ਨੂੰ ਬਿਨਾਂ ਪੂਰੇ ਰੀਫ੍ਰੈਸ਼ ਦੇ ਅਪਡੇਟ ਕਰਦੀ ਹੈ। ਵਾਪਸੀ ਆਕਾਰ ਛੋਟਾ ਅਤੇ typed ਰੱਖੋ ਤਾਂ ਕਿ ਬਦਲਾਅ ਸਮੀਖਿਆ ਵਿੱਚ ਆਸਾਨ ਰਹਿਣ।
ਕੋਡ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ edge cases ਨੂੰ ਚੁੱਕੋ: ਅਨਸੇਵੇਡ ਤਬਦੀਲੀਆਂ (confirm dialog ਦਿਖਾਓ), auth ਲੋੜੀਂਦੀ (login ਦੇ ਬਾਅਦ pauਸ ਅਤੇ resume), ਅਤੇ ਮਿਸਿੰਗ ਜਾਂ ਹਟੇ ਹੋਏ ਡੇਟਾ (error ਦਿਖਾਓ ਅਤੇ ਸਪਸ਼ਟ ਬਾਹਰ ਦਾ ਰਸਤਾ)。
ਜਦੋਂ ਤੁਸੀਂ ਤੇਜ਼ੀ ਨਾਲ ਇਟਰੇਟ ਕਰਦੇ ਹੋ, ਅਸਲੀ ਖਤਰਾ "ਗਲਤ UI" ਨਹੀਂ ਹੁੰਦਾ। ਖਤਰਾ ਇਹ ਹੈ ਕਿ UI ਸਮੀਖਿਆਯੋਗ ਨਹੀਂ ਰਹਿ ਜਾਂਦਾ। ਜੇ ਟੀਮੀਟ ਇਹ ਨਹੀਂ ਸਮਝ ਸਕਦਾ ਕਿ ਕੀ ਬਦਲਿਆ, ਕਿਉਂ ਬਦਲਿਆ, ਅਤੇ ਕੀ ਠੀਕ ਰਹਿ ਗਿਆ, ਤਾਂ ਹਰੇਕ ਅਗਲਾ ਇਟਰੇਸ਼ਨ ਧੀਮਾ ਹੋ ਜਾਂਦਾ ਹੈ।
ਇੱਕ ਨਿਯਮ ਜੋ ਮਦਦ ਕਰਦਾ ਹੈ: ਪਹਿਲਾਂ ਇੰਟਰਫੇਸ ਲਾਕ ਕਰੋ, ਫਿਰ ਇੰਟਰਨਲ ਨੂੰ ਹਿਲਣ ਦੀ ਆਗਿਆ ਦਿਓ। ਲੋਕਲ widget props (inputs), ਛੋਟੇ UI ਮਾਡਲ, ਅਤੇ route arguments ਨੂੰ ਸਥਿਰ ਕਰੋ। ਜਦੋਂ ਉਹਨਾਂ ਨੂੰ ਨਾਮ ਦਿੱਤਾ ਅਤੇ typed ਕੀਤਾ ਜਾਏ, ਤੁਸੀਂ widget tree ਨੂੰ ਬਿਨਾਂ ਐਪ ਦੇ ਹੋਰ ਹਿੱਸਿਆਂ ਨੂੰ ਟੁੱਟੇ ਬਦਲ ਸਕਦੇ ਹੋ।
ਜਨਰੇਟ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ diff-ਅਨੁਕੂਲ ਯੋਜਨਾ ਮੰਗੋ। ਤੁਸੀਂ ਇੱਕ ਯੋਜਨਾ ਚਾਹੁੰਦੇ ਹੋ ਜੋ ਦੱਸੇ ਕਿ ਕਿਹੜੀਆਂ ਫਾਇਲਾਂ ਬਦਲਣਗੀਆਂ ਅਤੇ ਕਿਹੜੀਆਂ ਛੱਡਣਗੀਆਂ। ਇਹ ਸਮੀਖਿਆ ਨੂੰ ਕੇਂਦ੍ਰਿਤ ਰੱਖਦਾ ਹੈ ਅਤੇ ਅਕਸਮਾਤੀ ਰੀਫੈਕਟਰਿੰਗ ਤੋਂ ਰੋਕਦਾ ਹੈ।
ਪੈਟਰਨ ਜੋ ਡਿਫ਼ ਛੋਟੇ ਰੱਖਦੇ ਹਨ:
ਕਹਾਣੀ: "As a shopper, I can edit my shipping address from checkout." ਪਹਿਲਾਂ route args ਲਾਕ ਕਰੋ: CheckoutArgs(cartId, shippingAddressId) ਸਥਿਰ ਰਹੇ। ਫਿਰ ਸਕਰੀਨ ਦੇ ਅੰਦਰ ਇਟਰੇਟ ਕਰੋ। ਜਦੋਂ ਲੇਆਉਟ ਸਥਿਰ ਹੋ ਜਾਏ, ਉਸਨੂੰ AddressForm, AddressSummary, ਅਤੇ SaveBar ਵਿੱਚ ਬਰਾਬਰ ਵੰਡੋ।
ਜੇ ਸਟੇਟ ਹੈਂਡਲਿੰਗ ਬਦਲਦੀ ਹੈ (ਉਦਾਹਰਨ ਲਈ, validation widget ਤੋਂ CheckoutController ਵਿੱਚ ਚਲੇ ਜਾਂਦੀ ਹੈ), ਸਮੀਖਿਆ ਪੜਨਯੋਗ ਰਹਿੰਦੀ ਹੈ: UI ਫਾਈਲਾਂ ਜ਼ਿਆਦਾਤਰ rendering ਬਦਲ ਦਿਖਾਉਂਦੀਆਂ ਹਨ, ਜਦਕਿ controller ਇੱਕ ਥਾਂ 'ਤੇ ਲਾਜਿਕ ਬਦਲ ਨੂੰ ਦਰਸਾਉਂਦਾ ਹੈ।
ਸਭ ਤੋਂ ਤੇਜ਼ੀ ਨਾਲ ਹੌਲੀ ਹੋਣ ਦਾ ਤਰੀਕਾ ਹੈ ਸਹਾਇਕ ਨੂੰ ਸਭ ਕੁਝ ਇੱਕ ਵਾਰੀ ਬਦਲਣ ਲਈ ਕਹਿਣਾ। ਜੇ ਇੱਕ commit layout, state, ਅਤੇ navigation ਤਿੰਨਨਾਂ ਨੂੰ ਛੇੜਦਾ ਹੈ, ਸਮੀਖਿਆਕਾਰ ਇਹ ਨਹੀਂ ਸਮਝ ਸਕਦੇ ਕਿ ਕੀ ਟੁੱਟਿਆ, ਅਤੇ rollback ਮੁਸ਼ਕਲ ਹੋ ਜਾਂਦਾ ਹੈ।
ਇੱਕ ਸੁਰੱਖਿਅਤ ਆਦਤ ਹੈ ਹਰ iteration ਲਈ ਇੱਕ ਮਨੋਰਥ: widget tree ਚੁਣੋ, ਫਿਰ state ਵਾਇਰ ਕਰੋ, ਫਿਰ ਨੈਵੀਗੇਸ਼ਨ ਜੋੜੋ।
ਇੱਕ ਆਮ ਸਮੱਸਿਆ Generated code ਨੂੰ ਹਰ ਸਕਰੀਨ 'ਤੇ ਇੱਕ ਨਵਾਂ ਪੈਟਰਨ ਸੋਚਣ ਦੇ ਦਿੰਦੀ ਹੈ। ਜੇ ਇਕ ਪੰਨਾ Provider ਵਰਤਦਾ ਹੈ, ਦੂਜਾ setState, ਅਤੇ ਤੀਜਾ ਇੱਕ ਕਸਟਮ controller ਕਲਾਸ, ਤਾਂ ਐਪ ਤੇਜ਼ੀ ਨਾਲ inconsistent ਹੋ ਜਾਂਦਾ ਹੈ। ਛੋਟੇ ਪੈਟਰਨਾਂ ਦੀ ਚੋਣ ਕਰੋ ਅਤੇ ਉਸ 'ਤੇ ਟਿਕੇ ਰਹੋ।
ਇੱਕ ਹੋਰ ਗਲਤੀ async ਕੰਮ ਨੂੰ ਸਿੱਧਾ build() ਵਿੱਚ ਰੱਖਣਾ ਹੈ। ਛੋਟੀ ਡੇਮੋ ਵਿੱਚ ਇਹ ਠੀਕ ਲੱਗ ਸਕਦਾ ਹੈ, ਪਰ ਇਹ rebuilds 'ਤੇ ਦੁਹਰਾਏ ਕਾਲਾਂ, ਫਲਿੱਕਰ, ਅਤੇ ਮੁਸ਼ਕਲ-ਟ੍ਰੇਸ ਬੱਗ ਲੈ ਆਉਂਦਾ ਹੈ। ਕਾਲ ਨੂੰ initState(), view model, ਜਾਂ dedicated controller ਵਿੱਚ ਰੱਖੋ, ਅਤੇ build() ਨੂੰ ਸਿਰਫ਼ rendering ਤੇ ਕੇਂਦ੍ਰਿਤ ਰੱਖੋ।
ਨਾਮਕਰਨ ਇੱਕ ਚੁਪ ਚਾਲੀ ਜਾਲ ਹੈ। ਕੋਡ ਜੋ ਕੰਪਾਈਲ ਹੁੰਦਾ ਹੈ ਪਰ ਪੜ੍ਹਨ 'ਚ Widget1, data2, ਜਾਂ temp ਵਰਗਾ ਹੈ, ਭਵਿੱਖ ਵਿੱਚ ਰੀਫੈਕਟਰਿੰਗ ਮਸ਼ਕਲ ਕਰਦਾ ਹੈ। ਸਾਫ਼ ਨਾਮ ਸਹਾਇਕ ਨੂੰ ਵੀ ਬਿਹਤਰ ਫਾਲੋਅਪ ਬਦਲਾਅ ਬਣਾਉਣ ਵਿੱਚ ਮਦਦ ਕਰਦੇ ਹਨ ਕਿਉਂਕਿ ਮਨੋਰਥ ਸਪਸ਼ਟ ਹੁੰਦਾ ਹੈ।
ਰੱਖਿਆ ਕਾਰਗਾਈਆਂ ਜੋ ਸਭ ਤੋਂ ਖਰਾਬ ਨਤੀਜੇ ਰੋਕਦੀਆਂ ਹਨ:
build() ਵਿੱਚ ਨੈੱਟਵਰਕ ਜਾਂ ਡੇਟਾਬੇਸ ਕਾਲਾਂ ਨਾ ਰੱਖੋਕਈ ਵਾਰ ਵਿਜ਼ੂਅਲ ਬੱਗ ਫਿਕਸ ਕਰਨ ਲਈ ਇੱਕ ਹੋਰ Container, Padding, Align, ਅਤੇ SizedBox ਜੋੜ ਦਿੱਤੇ ਜਾਂਦੇ ਹਨ। ਕੁਝ ਪਾਸਾਂ ਬਾਅਦ tree ਪੜ੍ਹਨਯੋਗ ਨਹੀਂ ਰਹਿੰਦਾ।
ਜੇ ਇੱਕ ਬਟਨ misaligned ਹੈ, ਪਹਿਲਾਂ wrappers ਹਟਾਉਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੋ, ਇੱਕ parent layout widget ਵਰਤੋਂ ਕਰੋ, ਜਾਂ ਇੱਕ ਛੋਟਾ widget ਅਲੱਗ ਕਰੋ ਜਿਸ ਦੇ ਆਪਣੇ constraints ਹਨ।
ਉਦਾਹਰਨ: checkout screen ਜਿੱਥੇ total price ਲੋਡ ਹੋਣ 'ਤੇ ਉਛਲਦਾ ਹੈ। ਇੱਕ ਸਹਾਇਕ ਕੀਮਤ ਰੋ ਨੂੰ "ਸਥਿਰ" ਕਰਨ ਲਈ ਹੋਰ widgets ਰੈਪ ਕਰਨ ਦੀ ਸਿਫ਼ਾਰਸ਼ ਕਰ ਸਕਦਾ ਹੈ। ਕੋਈ ਸਾਫ਼ ਸੁਧਾਰ ਹੈ ਕਿ loading ਲਈ ਥਾਂ ਰਿਜ਼ਰਵ ਕਰੋ ਇੱਕ ਸਧਾਰਨ loading placeholder ਨਾਲ ਅਤੇ row ਸੰਰਚਨਾ ਨੂੰ ਬਦਲਿਆ ਬਿਨਾਂ ਰੱਖੋ।
ਕਮੇਟ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਦੋ ਮਿੰਟ ਦਾ ਪਾਸ ਕਰੋ ਜੋ ਯੂਜ਼ਰ ਮੁੱਲ ਦੀ ਜਾਂਚ ਕਰੇ ਅਤੇ ਆਚਾਨਕ ਰਿਗਰੈਸ਼ਨ ਤੋਂ ਬਚਾਏ। ਮਕਸਦ ਪਰਫੈਕਸ਼ਨ ਨਹੀਂ; ਇਹ ਯਕੀਨੀ ਬਣਾਉਣਾ ਹੈ ਕਿ ਇਹ iteration ਆਸਾਨੀ ਨਾਲ ਸਮੀਖਿਆਯੋਗ, ਟੈਸਟਯੋਗ, ਅਤੇ ਵਾਪਸ ਕਰਨਯੋਗ ਹੈ।
ਇੱਕ ਵਾਰੀ ਯੂਜ਼ਰ ਕਹਾਣੀ ਪੜ੍ਹੋ, ਫਿਰ ਹੇਠ ਲਿਖੀਆਂ ਚੀਜ਼ਾਂ ਨੂੰ ਚੱਲ ਰਹੀ ਐਪ (ਜਾਂ ਇੱਕ ਸਧਾਰਨ widget test) ਨਾਲ ਸਾਥ ਕਰੋ:
ਇੱਕ ਛੋਟਾ ਰੀਅਲਟੀ ਚੈੱਕ: ਜੇ ਤੁਸੀਂ ਇੱਕ ਨਵੀਂ Order details screen ਜੋੜੀ, ਤਾਂ ਤੁਹਾਨੂੰ (1) list ਤੋਂ ਉਸਨੂੰ ਖੋਲ੍ਹਣਾ ਚਾਹੀਦਾ ਹੈ, (2) ਇੱਕ loading spinner ਦੇਖਣਾ, (3) ਇੱਕ error simulate ਕਰ ਸਕਣਾ, (4) ਖਾਲੀ order ਦੇਖਣਾ, ਅਤੇ (5) back ਦਬਾਕੇ ਵਾਪਸ list ਤੇ ਆਉਣਾ ਬਿਨਾਂ ajeeb jumps ਦੇ।
ਜੇ ਤੁਹਾਡਾ ਵਰਕਫਲੋ snapshots ਅਤੇ rollback ਸਹਾਇਤਾ ਕਰਦਾ ਹੈ, ਤਾਂ ਵੱਡੇ UI ਬਦਲਾਵਾਂ ਤੋਂ ਪਹਿਲਾਂ snapshot ਲਓ। ਕੁਝ ਪਲੇਟਫਾਰਮ ਜਿਵੇਂ Koder.ai ਇਹ ਸਹਾਇਤਾ ਦਿੰਦੇ ਹਨ, ਅਤੇ ਇਹ ਤੁਹਾਨੂੰ ਤੇਜ਼ੀ ਨਾਲ ਇਟਰੇਟ ਕਰਨ ਵਿੱਚ ਮਦਦ ਕਰ ਸਕਦਾ ਹੈ ਬਿਨਾਂ main branch ਨੂੰ ਖ਼ਤਰੇ ਵਿੱਚ ਪਾਏ।
ਯੂਜ਼ਰ ਕਹਾਣੀ: "As a shopper, I can browse items, open a details page, save an item to favorites, and later view my favorites." ਲਕੜੀ ਇਹ ਹੈ ਕਿ ਸ਼ਬਦਾਂ ਤੋਂ ਸਕ੍ਰੀਨਾਂ ਤੱਕ ਤਿੰਨ ਛੋਟੇ, ਸਮੀਖਿਆਯੋਗ ਕਦਮਾਂ ਵਿੱਚ ਜਾਇਆ ਜਾਵੇ।
Iteration 1: ਸਿਰਫ਼ browse list screen 'ਤੇ ਧਿਆਨ ਦਿਓ। ਇੱਕ widget tree ਬਣਾਓ ਜੋ render ਕਰਨ ਲਈ ਕਾਫ਼ੀ ਹੈ ਪਰ ਅਸਲ ਡੇਟਾ ਨਾਲ ਜੁੜੀ ਨਹੀਂ: ਇੱਕ Scaffold ਨਾਲ AppBar, ਇੱਕ ListView placeholder rows ਨਾਲ, ਅਤੇ loading ਅਤੇ empty states ਲਈ ਸਪਸ਼ਟ UI। ਸਟੇਟ ਸਧਾਰਨ ਰੱਖੋ: loading (CircularProgressIndicator ਦਿਖਾਓ), empty (ਛੋਟਾ ਸੁਨੇਹਾ ਅਤੇ ਸ਼ਾਇਦ Try again button), ਅਤੇ ready (list ਦਿਖਾਓ)।
Iteration 2: details screen ਅਤੇ navigation ਜੋੜੋ। ਸਪਸ਼ਟ ਰਹੋ: onTap ਇੱਕ ਰੂਟ push ਕਰਦਾ ਹੈ ਅਤੇ ਇੱਕ ਛੋਟੇ parameter object (ਉਦਾਹਰਨ: item id, title) ਨੂੰ ਭੇਜਦਾ ਹੈ। details page read-only ਨਾਲ ਸ਼ੁਰੂ ਕਰੋ: title, description placeholder, ਅਤੇ Favorite action button। ਮਕਸਦ ਕਹਾਣੀ ਨਾਲ ਮੇਲ ਕਰਨਾ ਹੈ: list -> details -> back, ਬਿਨਾਂ ਵਧੇਰੇ ਫਲੋ।
Iteration 3: favorites state updates ਅਤੇ UI ਫੀਡਬੈਕ ਲਾਓ। favorites ਲਈ ਇੱਕ single source of truth ਜੋੜੋ (ਭਾਵੇਂ ਇਹ ਅਜੇ ਵੀ in-memory ਹੋਵੇ), ਅਤੇ ਦੋਹਾਂ ਸਕਰੀਨਾਂ ਵਿੱਚ ਇਸ ਨੂੰ ਵਾਇਰ ਕਰੋ। Favorite ਟੈਪ ਕਰਨ 'ਤੇ icon ਤੁਰੰਤ ਅਪਡੇਟ ਹੋਵੇ ਅਤੇ ਇੱਕ ਛੋਟੀ ਪੁਸ਼ਟੀ (ਜਿਵੇਂ SnackBar) ਦਿਖਾਓ। ਫਿਰ ਇੱਕ Favorites screen ਜੋ ਉਹੀ state ਪੜ੍ਹਦਾ ਹੈ ਅਤੇ empty/list UI ਨੂੰ ਸੰਭਾਲਦਾ ਹੈ।
ਸਮੀਖਿਆਯੋਗ diff ਆਮ ਤੌਰ 'ਤੇ ਇਉਂ ਦਿੱਖਦਾ ਹੈ:
browse_list_screen.dart: widget tree ਨਾਲ loading/empty/ready UIitem_details_screen.dart: UI ਲੇਆਉਟ ਅਤੇ navigation params ਲੈਂਦਾ ਹੈfavorites_store.dart: ਘੱਟੋ-ਘੱਟ state holder ਅਤੇ update methodsapp_routes.dart: routes ਅਤੇ typed navigation helpersfavorites_screen.dart: state ਪੜ੍ਹਦਾ ਹੈ ਅਤੇ empty/list UI ਦਿਖਾਉਂਦਾ ਹੈਜੇ ਕੋਈ ਇੱਕ ਫਾਈਲ "ਜਿੱਥੇ ਸਭ ਕੁਝ ਹੁੰਦਾ ਹੈ" ਬਣ ਜਾਏ, ਅੱਗੇ ਵਧਣ ਤੋਂ ਪਹਿਲਾਂ ਇਸਨੂੰ ਵੰਡੋ। ਛੋਟੀਆਂ ਫਾਈਲਾਂ ਜੀਨਾਂ ਦੇ ਸਾਫ਼ ਨਾਮ ਹਨ, ਅਗਲੇ iteration ਨੂੰ ਤੇਜ਼ ਅਤੇ ਸੁਰੱਖਿਅਤ ਰੱਖਦੀਆਂ ਹਨ।
ਜੇ ਵਰਕਫਲੋ صرف ਜਦੋਂ ਤੁਸੀਂ "ਜੁਮ ਵਿੱਚ" ਹੋ ਤਾਂ ਹੀ ਕੰਮ ਕਰਦਾ ਹੈ, ਇਹ ਤਦ ਤੋੜ ਜਾਵੇਗਾ ਜਦੋਂ ਤੁਸੀਂ ਸਕਰੀਨ ਬਦਲੋਂਗੇ ਜਾਂ ਕੋਈ ਟੀਮੀਟ ਫੀਚਰ ਨੂੰ ਛਵੇ। ਇਸ ਲੂਪ ਨੂੰ ਆਦਤ ਬਣਾਉਣ ਲਈ ਇਹ ਲਿਖੋ ਅਤੇ ਬਦਲਾਅ ਦੇ ਆਕਾਰ 'ਤੇ ਗਾਰਡਰੇਲ ਸੈੱਟ ਕਰੋ।
ਇੱਕ ਟੀਮ ਟੈਂਪਲੇਟ ਵਰਤੋਂ ਤਾਂ ਕਿ ਹਰ iteration ਇੱਕੋ ਹੀ ਇਨਪੁੱਟ ਨਾਲ ਸ਼ੁਰੂ ਹੋਵੇ ਅਤੇ ਏਸੇ ਕਿਸਮ ਦੇ ਆਉਟਪੁੱਟ ਉਤਪੰਨ ਹੋਣ। ਛੋਟਾ ਪਰ ਨਿਰਧਾਰਤ ਰੱਖੋ:
ਇਸ ਨਾਲ ਸਹਾਇਕ ਦੁਆਰਾ feature ਵਿਚ ਮੱਝੋ-ਮੱਝ ਹੋਰ ਨਵੇਂ ਪੈਟਰਨ ਦੀ ਸੰਭਾਵਨਾ ਘੱਟ ਹੁੰਦੀ ਹੈ।
ਇੱਕ ਪਰਿਭਾਸ਼ਾ ਚੁਣੋ ਜੋ code review ਵਿੱਚ ਲਾਗੂ ਕਰਨੀ ਆਸਾਨ ਹੋ। ਉਦਾਹਰਨ ਲਈ, ਹਰ iteration ਨੂੰ ਫਾਇਲਾਂ ਦੀ ਸਿਮਤ ਗਿਣਤੀ 'ਤੇ ਸੀਮਿਤ ਕਰੋ, ਅਤੇ UI refactors ਨੂੰ ਵਿਹਾਰ ਬਦਲਾਅ ਤੋਂ ਵੱਖ ਰੱਖੋ।
ਸਧਾਰਨ ਨਿਯਮ:
ਬੁਰੀ ਕਦਮ ਨੂੰ ਤੇਜ਼ੀ ਨਾਲ ਵਾਪਸ ਕਰਨ ਲਈ checkoints ਜੋੜੋ। ਘੱਟੋ-ਘੱਟ commits ਨੂੰ ਟੈਗ ਕਰੋ ਜਾਂ ਵੱਡੇ ਰੀਫੈਕਟਰ ਤੋਂ ਪਹਿਲਾਂ ਲੋਕਲ checkpoints ਰੱਖੋ। ਜੇ ਤੁਹਾਡਾ ਵਰਕਫਲੋ snapshots ਅਤੇ rollback ਸਹਾਇਤਾ ਕਰਦਾ ਹੈ, ਤਾਂ ਉਹਨਾਂ ਦਾ ਬਹੁਤ ਜ਼ਿਆਦਾ ਵਰਤੋ।
If you want a chat-based workflow that can generate and refine Flutter apps end to end, Koder.ai includes a planning mode that helps you review a plan and expected file changes before applying them.
Use a small, testable UI spec first. Write 3–6 lines that cover:
Then build only that slice (often one screen + 1–2 widgets).
Convert the story into four buckets:
If you can’t describe the acceptance check quickly, the story is still too fuzzy for a clean UI diff.
Start by generating only a widget tree outline (names + hierarchy + what each part shows). No code.
Then request a component responsibility breakdown (what each widget owns).
Only after that, generate the stateless scaffold with explicit inputs (values + callbacks), and do styling in a separate pass.
Treat it as a hard rule: one intent per iteration.
If a single commit changes layout, state, and routes together, reviewers won’t know what caused a bug, and rollback gets messy.
Keep widgets “dumb”: they should render state, not decide business rules.
A practical default:
Avoid putting async calls in build()—it leads to repeated calls on rebuild.
Define states and transitions in plain English before coding.
Example pattern:
Then list events that move between them (refresh, retry, submit, edit). Code becomes easier to compare against the written rules.
Write a tiny “flow map” for the story:
Also lock down what travels between screens (IDs, filters, draft data) so you don’t end up hiding context in globals.
Default to feature-first folders so changes stay contained. For example:
lib/features/<feature>/screens/lib/features/<feature>/widgets/lib/features/<feature>/state/lib/features/<feature>/routes.dartThen keep each iteration focused on one feature folder and avoid drive-by refactors elsewhere.
A simple rule: stabilize interfaces, not internals.
Reviewers care most that inputs/outputs stayed stable even if the layout moved around.
Do a two-minute pass:
If your workflow supports it (for example snapshots/rollback), take a snapshot before a bigger layout refactor so you can revert safely.